svenwltr svenwltr - 16 days ago 6
Python Question

How to use custom AdminSite class?

Which is the best way to implement my own

django.contrib.admin.sites.AdminSite
?

Actually I get a problem with the registration of
INSTALLED_APPS
in
django.contrib.admin.autodiscover
. If I use my custom AdminSite class in
urls.py
, there were no apps displayed on the admin page.

I fixed this with a litte hack. I wrote this class:

from django.contrib.admin.sites import site as default_site

class AdminSiteRegistryFix( object ):
'''
This fix links the '_registry' property to the orginal AdminSites
'_registry' property. This is necessary, because of the character of
the admins 'autodiscover' function. Otherwise the admin site will say,
that you havn't permission to edit anything.
'''

def _registry_getter(self):
return default_site._registry

def _registry_setter(self,value):
default_site._registry = value

_registry = property(_registry_getter, _registry_setter)


And implement my custom AdminSite like this:

from wltrweb.hacks.django.admin import AdminSiteRegistryFix
from django.contrib.admin import AdminSite

class MyAdminSite( AdminSite, AdminSiteRegistryFix ):
# do some magic
pass


site = MyAdminSite()


So I can use this
site
for
urls.py
.

Anyone knows a better way? Since I access a var starting with a underscore it is no more than a hack. I don't like hacks.

Edit: Another way would be to rewrite the
django.contrib.admin.autodiscover
function, but in this case I would have redundant code.

Answer

Quoting from https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#customizing-the-adminsite-class

If you'd like to set up your own administrative site with custom behavior, however, you're free to subclass AdminSite and override or add anything you like. Then, simply create an instance of your AdminSite subclass (the same way you'd instantiate any other Python class), and register your models and ModelAdmin subclasses with it instead of using the default.

I guess that is the most explicit approach, but it also means that you need to change the register code in your apps admin.py files.

There is really no need to use autodiscover when using your own AdminSite instance since you will likely be importing all the per-app admin.py modules in your myproject.admin module.

The assumption seems to be, that once you start writing your custom admin site, it becomes pretty much project specific and you know beforehand which apps you want to include.

So if you don't want to work with the hack above, I only really see these two options. Replace all register calls to your custom admin site or register the models explicitly in your adminsite module.