Django: Using 2 different AdminSite instances with different models registered
- by omat
Apart from the usual admin, I want to create a limited admin for non-staff users. This admin site will have different registered ModelAdmins.
I created a folder /useradmin/ in my project directory and similar to contrib/admin/_init_.py I added an autodiscover() which will register models defined in useradmin.py modules instead of admin.py:
# useradmin/__init__.py
def autodiscover():
# Same as admin.autodiscover() but registers useradmin.py modules
...
for app in settings.INSTALLED_APPS:
mod = import_module(app)
try:
before_import_registry = copy.copy(site._registry)
import_module('%s.useradmin' % app)
except:
site._registry = before_import_registry
if module_has_submodule(mod, 'useradmin'):
raise
I also cretated sites.py under useradmin/ to override AdminSite similar to contrib/admin/sites:
# useradmin/sites.py
class UserAdminSite(AdminSite):
def has_permission(self, request):
# Don't care if the user is staff
return request.user.is_active
def login(self, request):
# Do the login stuff but don't care if the user is staff
if request.user.is_authenticated():
...
else:
...
site = UserAdminSite(name='useradmin')
In the project's URLs:
# urls.py
from django.contrib import admin
import useradmin
admin.autodiscover()
useradmin.autodiscover()
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
(r'^useradmin/', include(useradmin.site.urls)),
)
And I try to register different models in admin.py and useradmin.py modules under app directories:
# products/useradmin.py
import useradmin
class ProductAdmin(useradmin.ModelAdmin):
pass
useradmin.site.register(Product, ProductAdmin)
But when registering models in useradmin.py like useradmin.site.register(Product, ProductAdmin), I get 'module' object has no attribute 'ModelAdmin' exception. Though when I try this via shell;
import useradmin
from useradmin import ModelAdmin
does not raise any exception.
Any ideas what might be wrong?
Edit:
I tried going the @Luke way and arranged the code as follows as minimal as possible:
(file paths are relative to the project root)
# admin.py
from django.contrib.admin import autodiscover
from django.contrib.admin.sites import AdminSite
user_site = AdminSite(name='useradmin')
# urls.py (does not even have url patterns; just calls autodiscover())
import admin
admin.autodiscover()
# products/admin.py
import admin
from products.models import Product
admin.user_site.register(Product)
As a result I get an AttributeError: 'module' object has no attribute 'user_site' when admin.user_site.register(Product) in products/admin.py is called.
Any ideas?
Solution:
I don't know if there are better ways but, renaming the admin.py in the project root to useradmin.py and updating the imports accordingly resolved the last case, which was a naming and import conflict.