Multiple Django admin sites
Throughout this chapter, you've
learned the Django admin site is activated under the
/admin/
url using
django.contrib.admin.site.urls
. In addition, the
Django admin site also requires the definition of Django admin
classes to be placed inside a Django project's app
admin.py
files and registered using one of the
techniques described in listing 11-1 (e.g.
django.contrib.admin.site.register(Store,StoreAdmin)
)
While this is the standard
practice for almost all Django admin site installations, this
process can differ for cases when you want or need to set up
multiple Django admin sites. This of course begets the question
'
Why would you want or need multiple Django admin
sites ?'
Mulitple Django admin sites are helpful because they let you separate the access locations for different types of users or groups. For example, you can have a Django admin site designed to let employees perform CRUD operations across different models, while having a completely different Django admin site designed to let providers perform more limited CRUD operations across another set of models.
If you maintain a single Django admin site, creating a solution for multiple types of users and models can be very difficult as you only have user permissions to enforce CRUD operation access, as described in the previous section. With multiple Django admin sites, you can register models in one or both admin sites depending on your requirements.
The first step to create multiple
Django admin sites is to create multiple instances of the
django.contrib.admin.AdminSite
class, as illustrated
in listing 11-26
Listing 11-26. Django admin multiple sites accessible on different urls.
# urls.py (Main directory) from django.conf.urls import include, url from django.views.generic import TemplateView from django.contrib import admin admin.site.site_header = 'Coffeehouse general admin' from coffeehouse.admin import employeeadmin, provideradmin urlpatterns = [ url(r'^$',TemplateView.as_view(template_name='homepage.html'),name="homepage"), url(r'^admin/', admin.site.urls), url(r'^employeeadmin/', employeeadmin.urls), url(r'^provideradmin/', provideradmin.urls), ] # admin.py (Main directory) from django.contrib.admin import AdminSite class EmployeeAdminSite(AdminSite): site_header = 'Coffeehouse Employee admin' employeeadmin = EmployeeAdminSite(name='employeeadmin') class ProviderAdminSite(AdminSite): site_header = 'Coffeehouse Provider admin' provideradmin = ProviderAdminSite(name='provideradmin')
First, notice listing 11-26
declares the standard Django admin with the
django.contrib.admin
class in urls.py
,
including a custom site_header
value to mount the
Django admin on the standard /admin/
url. Next, two
custom Django admin instances are configured on their own urls --
/employeeadmin/
and /provideradmin/
--
using a urls
reference that corresponds to a custom
django.contrib.admin.AdminSite
class.
Both the
EmployeeAdminSite
and ProviderAdminSite
custom Django admin site classes are defined in their own
admin.py
file in the top level directory of the
project (i.e. alongside the main urls.py
file). Notice
how each of the custom Django admin site classes inherits its
behavior from the django.contrib.admin.AdminSite
class. Next, observe how each instance of the
AdminSite
classes in listing 11-26, also defines the
site_header
field to define a custom header for each
Django admin site instance, just like it's done with the standard
Django admin site.
At this juncture, if you visit
either the /employeeadmin/
and
/provideradmin/
urls for the custom Django admins,
you'll access a main Django admin page like the one in figure
11-47. The reason you'll see an empty Django admin page in both
cases, is because each custom Django admin site still doesn't have
any models registered to it.
To register Django admin classes
with a custom Django admin site, you can use any of the techniques
already described in listing 11-1. The difference though is you
must register a Django admin class with an instance of a specific
Django admin site (e.g. employeeadmin
,
provideradmin
) instead of the default
django.contrib.admin
class, as illustrated in listing
11-27.
Listing 11-27. Django admin class registration on multiple Django admin sites
# admin.py (stores app) from django.contrib import admin from coffeehouse.stores.models import Store,Amenity class StoreAdmin(admin.ModelAdmin): search_fields = ['city','state'] # Default model registration on main Django admin admin.site.register(Store, StoreAdmin) # Model registration on custom Django admin named provideradmin from coffeehouse.admin import provideradmin provideradmin.register(Store, StoreAdmin) # admin.py (items app) from django.contrib import admin from coffeehouse.items.models import Menu class MenuAdmin(admin.ModelAdmin): list_display = ['name','creator'] # Default model registration on main Django admin admin.site.register(Menu, MenuAdmin) # Model registration on custom Django admin named provideradmin from coffeehouse.admin import employeeadmin employeeadmin.register(Menu, MenuAdmin)
Notice in listing 11-27, that in
addition to the default Django admin class registration done
through admin.site.register
, the Store
class is registered with the custom provideradmin
Django admin class and the Menu
class is registered
with the custom employeeeadmin
Django admin class,
both of which are the custom Django admin classes declared in
listing 11-26.
As you can see in listing 11-27, it's perfectly valid to register the same Django admin class on multiple Django admin sites, a process that allows you to selectively access certain models under different Django admin sites.
Caution Multiple Django admin sites don't preclude user permissions, authentication or url visibility. By default, all Django users can use the same credentials and are assigned the same permissions across multiple Django admin sites. This means it's up to you to enforce effective model permissions across all Django admin sites, limit model registration for each Django admin site, as well as avoid easy to guess Django admin urls to avoid unintended access.