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.
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
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
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 --
urls reference that corresponds to a custom
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
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
/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.
provideradmin) instead of the default
django.contrib.admin class, as illustrated in listing
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
class is registered with the custom
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
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.