How to change django admin "view site" link to custom absolute url - python

I have REST API built on Django and JS application. Both are on different domains. How to change django admin "VIEW SITE" link in such way so it will open JS application? I've tried to pass absolute link (https://docs.djangoproject.com/es/1.10/ref/contrib/admin/#django.contrib.admin.AdminSite.site_url), but looks like it does not work - only relative paths allowed

I prefer resetting admin.site.site_url in urls.py, along with other site changes (instead of doing this in an admin.py file, cause a project can have serveral admin.py)
# urls.py
admin.site.site_url = '' # Removes the 'View Site' link
admin.site.site_header = 'My Site'

In Django 1.11.5, it seems that :
from django.contrib import admin and
admin.site.site_url = 'https:....' in the admin.py file is enough

By default , "VIEW SITE" points to '/' i.e localhost:8000 (Default settings assumed).
To change it , use (in admin.py):
admin.site.site_url = "/mySite"
Tested on Django 2.1

There are two solutions I can come up with.
Firstly, you could use custom template admin/base.html. But, reading through the default template, you would have to copy-paste a lot of code just to change a link, which seems like an overkill.
Another solution involves overriding AdminSite. AdminSite has a property called site_url, and it seems like changing it would do the job. So, in essense, you can do something like this:
your_app/admin.py
from django.contrib.admin import AdminSite
from .models import MyModel
class MyAdminSite(AdminSite):
site_url = 'https://yourdomain.com'
admin_site = MyAdminSite(name='myadmin')
your_project/urls.py
from django.conf.urls import url
from myapp.admin import admin_site
urlpatterns = [
url(r'^myadmin/', admin_site.urls),
]
And you should register all your models with your custom admin, not Django's default:
from your_app.admin import admin_site
admin_site.register(MyModel)

Default link to viewsite is http://127.0.0.1:8000/
We can change it to custom url through register it in admin.py
admin.site.site_url = "/mySite"
Example : admin.py
from django.contrib import admin
from auth_app.models import profile
# Register your models here.
admin.site.register(profile)
#register link
admin.site.site_url = "/mySite"

In admin.py, mention your custom path like following
admin.site.site_url = "/<Your Path>"
If your custom url is like "https://example.com/dashboard", You have to put below line in your admin.py
admin.site.site_url = "/dashboard"

You can change "VIEW SITE" link by changing "admin.site.site_url" which is "/" by default:
from django.contrib import admin
print(admin.site.site_url) # /
admin.site.site_url = "/example"

Related

How to change the database name display in django admin site?

Is it possible to change change the database name in django admin site?
Just like how I change the following:
admin.site.site_header = "Administrator"
admin.site.site_title = "Administrator"
admin.site.index_title = "Admin"
There are two options, you can do it manually, or you can do it through the help of an external python library
Manually
is by creating custom AdminSite
admin.py
from django.contrib.admin import AdminSite
from django.utils.translation import ugettext_lazy
class MyAdminSite(AdminSite):
# Text to put at the end of each page's <title>.
site_title = ugettext_lazy('My site admin')
# Text to put in each page's <h1> (and above login form).
site_header = ugettext_lazy('My administration')
# Text to put at the top of the admin index page.
index_title = ugettext_lazy('Site administration')
admin_site = MyAdminSite()
urls.py
from django.conf.urls import patterns, include
from myproject.admin import admin_site
urlpatterns = patterns('',
(r'^admin/', include(admin_site.urls)),
)
by using python package
you can use the python package called django-admin-interface
pip install django-admin-interface
you'll need to import it into your settings.py
INSTALLED_APPS = (
#...
"admin_interface",
"flat_responsive", # only if django version < 2.0
"flat", # only if django version < 1.9
"colorfield",
#...
"django.contrib.admin",
#...
)
# only if django version >= 3.0
X_FRAME_OPTIONS = "SAMEORIGIN"
SILENCED_SYSTEM_CHECKS = ["security.W019"]
after installing it, you'll be able to customize your admin panel from the themes menu inside your admin panel
You can change the app name by adding verbose_name under app.py
from django.apps import AppConfig
class PharmacyConfig(AppConfig):
name = 'pharmacy'
verbose_name = 'Your Home Page'

django admin remove login page

Is there anyway to delete django admin login page (mySite.com/admin) and use the user session which has logged in in main site (mySite.com)?
If any code is needed please tell me to add.
My middleware in settings.py is:
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
.
.
.
.
.
]
update:
the reason is I want the admin first logs in with his account in website then open admin page. Other users would see admin link, but after clicking that they would see a message you don't have permission to see or change anything and they see nothing else. I just want myWebsite.com/admin be redirected to admin:index if the user is logged in and to myWebsite.com if he is not.
You can easily do this using your main urls.py file. Just redirect the admin login URL to your custom log-in page on your website. In the below sample you will notice the normal admin.site.urls being used AFTER admin/login and admin/logout (I assume you'll also have a custom log-out page). With these custom views being first they will take precedence and be used instead of the ones in admin.site.urls.
urlpatterns = [
url(r'^admin/login', your_custom_login_view, name='custom_login_page_admin'),
url(r'^admin/logout', your_custom_logout_view, name='custom_logout_view_admin'),
url(r'^admin/', admin.site.urls),
]
Create a custom subclass of AdminSite and overwrite the login() method. Something like this:
class CustomAdminSite(admin.AdminSite):
def login(self, request, extra_context=None):
if not request.user.is_authenticated:
# not authenticated, redirect to main login page
login_path = reverse('login')
return HttpResponseRedirect(login_path)
if self.has_permission(request):
# Already logged-in, redirect to admin index
index_path = reverse('admin:index', current_app=self.name)
return HttpResponseRedirect(index_path)
else:
# Logged in, but doesn't have required permissions
return render(...) # render a template with your error message
Follow the Django documentation on how to customize the AdminSite class.
Why you want to do that? Admin Page is for admin purposes, just dont access /admin/ path anymore or just remove admin from your urls.py, doign that you will not be able to access admin pages anymore...
But if you want to make your users access your django admin native pages using your custom login page, just make sure to tag your users with is_staff so they can access native django pages...
models.py
from django.contrib.auth.models import User
class CustomUser(User):
... # Your new fields
views.py
def create_user(request):
...
user, created = CustomUser.objects.get_or_created(
... # Your Custom + User Django fields
is_staff = True # This will allow this user to access the admin page
)
If you want allow all your users to access your django admin pages without need to use Django Login Page you can override your CustomUser model to set all users with is_staff
class CustomUser(User):
... # Your new fields
def save(self, *args, **kwargs):
if not self.id: # This indentify if the registry is new...
self.is_staff = True
super(CustomUser, self).save(*args, **kwargs)
Obs.: Make sure your User models extends the Django User Auth, there 2... one more complex and one simple, check the docs
https://docs.djangoproject.com/en/2.0/ref/contrib/auth/
All mentioned solutions here might do a good job, but my solution would be a little different: If you want to redirect to your default login page and hide the django-admin, sth. simple like this is a good workaround:
urlpatterns = [
path('admin/login/', RedirectView.as_view(pattern_name='account_login', permanent=True)),
]
Of course the target route (here account_login) can be changed as desired.
I prefer this approach:
on urls.py
from .settings import LOGIN_URL
from django.views.generic import RedirectView,
from django.urls import path, include
from django.contrib import admin
urlpatterns = [
path('admin/login/', RedirectView.as_view(url=LOGIN_URL)),
path('admin/', admin.site.urls),
....
]
To disable admin just remove url(r'^admin/', admin.site.urls), from your main urls.py. Another things to clean are 'django.contrib.admin' from INSTALLED_APPS.
A real easy way to accomplish this is by doing 2 things:
Head to your settings.py file and add: ADMIN_ENABLED = False
Head to your main urls.py file which should have something that looks like:
from django.urls import path, include
urlpatterns = [
# path('admin/', admin.site.urls),
path('', include("landing.urls")),
]
and comment out the path to admin like in the above snippet.
Cheers!

Add view in the bottom of Django modeladmin

I have a blog made with Django where I write posts in markdown. I would like to add a view in the bottom of the admin page for each instance of the class Entry (my blog post class) such that I can get a preview of what the markdown looks like, while I'm writing. Just as you get a preview here on Stack Overflow when you create a new post.
I already have an admin class extending ModelAdmin:
class EntryAdmin(admin.ModelAdmin):
list_display = ('title','created')
prepopulated_fields = {'slug': ('title',)}
Is it possible to modify ModelAdmin further, such that it loads a certain html file (blogpost.html) and shows it in the bottom of the admin page?
I made a picture to show exactly what I mean:
NB: I know there are various tools such as Django admin plus, that allows one to add views to the admin interface, but not for each instance of an object.
You can use markdownx for that:
pip install django-markdownx
project settings.py
INSTALLED_APPS =
#. . . .
'markdownx',
]
project urls.py
urlpatterns = [
#[...]
url(r'^markdownx/', include('markdownx.urls')),
]
and then collect static files.
python3 manage.py collectstatic
your models.py
from markdownx.models import MarkdownxField
class MyModel(models.Model):
myfield = MarkdownxField()
your app admin.py
from django.contrib import admin
from markdownx.admin import MarkdownxModelAdmin
from .models import MyModel
admin.site.register(MyModel, MarkdownxModelAdmin)
This should work.

Django display user uploaded content

I have yet to wrap my head around django and URLs, and my confusion is now preventing me from doing what I feel like should be a very simple task.
I have successfully implemented file upload.
In my settings.py file, I have added the specifications for where to store the uploaded files and the URL Django should use to serve them.
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL= '/media/'
I also added the necessary line to urls.py to allow Django to serve files from MEDIA_URL.
from django.conf.urls import url, include
from django.contrib import admin
from login_app import views as login_app_views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', login_app_views.login_user),
# creating registered namespaces for each app
url(r'^login/', include('login_app.urls', namespace = "login_app")),
url(r'^CMIRS/', include('dashboard_app.urls', namespace = "dashboard_app")),
url(r'^CMIRS/', include('submit_app.urls', namespace = "submit_app")),
url(r'^CMIRS/', include('filter_app.urls', namespace = "filter_app")),
url(r'^CMIRS/case/',include('report_app.urls', namespace = "report_app")),
url(r'^CMIRS/', include('search_app.urls', namespace = "search_app")),
url(r'^search/', include('haystack.urls')), ##used in navbar-search
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
In an app report_app, I want the webpage to display a hyperlink that can be used to view an uploaded file. When I click on the hyperlink, I want it to request the URL to the uploaded file.
The upload looks like such in my models:
upload1 = models.FileField(upload_to = 'documents/%Y/%m/%d/')
I am having trouble figuring out what to use in the render(request) in my view and how to correctly code this in HTML. When I attempt to use "media", I get an error saying it cannot be matched.
Here is a snippet of the HTML I am trying:
<dt>Upload</dt><dd><tr><td>{{ case.upload1 }}</td></tr></dd>
I am also confused as how to set up my render(request) so that it knows to access media/, and then go to the correct documents/Y/M/D depending on the primary key.
You don't want to use the url tag here at all. Your media's URL is stored in your model, and has nothing to do with Django's path resolution logic. Just reference the url method of the field:
<a href="{{ case.upload1.url }}">
See the docs.
(Note also that serving files via your urls.py like this works in dev only; for prod you'll need to configure your webserver to do it.)

Get rid of default view in Satchmo / Django?

just curious what's the proper/transparent way to get plain 404 error instead of view for the pre-defined url ?
The default install of Satchmo handles /quickorder url with a cart view. I would like to completely disable handling for this url. So far I did get is the following url replacement in url.py at the top of store tree:
from django.conf.urls.defaults import *
from satchmo_store.urls import urlpatterns
from satchmo_utils.urlhelper import replace_urlpattern
replace_urlpattern(
urlpatterns,
url(r'^quickorder/$', handler404)
)
The handler404 is from django.conf.urls.defaults but it returns Django's own content instead of the shop's default 404 page like if you would ask for a non-existent page like http://www.google.com/quickorder_somenonsenseintheurl.
Any idea how to override this while avoiding modifications of default Satchmo installation ?

Categories

Resources