Django 3.2 admin后台添加带权限校验自定义视图的最简方法
问题原因
你自定义的MyAdminSite实例admin_site完全独立于Django默认的admin.site实例。默认django.contrib.admin自动执行的autodiscover()操作,会把所有应用admin.py中注册的模型全部绑定到默认admin.site上,而非你自己定义的admin_site,所以才会出现后台管理项显示不全的问题。你当前使用的直接修改_registry私有属性的方案不符合Django最佳实践,版本升级时可能出现兼容问题。
方案1:规范使用自定义AdminSite的实现
如果你确实需要自定义AdminSite全局能力,可通过以下方式解决注册问题:
- 方式一:全量手动注册
所有应用的admin.py中,不再使用默认的admin.site.register(模型类),而是导入你自定义的admin_site实例,改为admin_site.register(模型类)完成注册,适合需要完全隔离自定义站点与默认站点的场景。 - 方式二:自动同步默认站点注册内容
无需修改现有应用的注册代码,直接在自定义AdminSite的文件末尾执行自动发现和同步即可:
from django.contrib import admin from django.contrib.admin import site as default_site from django.template.response import TemplateResponse from django.urls import path class MyAdminSite(admin.AdminSite): def get_urls(self): urls = super().get_urls() # admin_view是Admin自带的权限校验装饰器,和其他admin页面校验规则一致 my_urls = [ path('my-view', self.admin_view(self.my_view), name='my-view') ] return my_urls + urls def my_view(self, request): # 继承admin全局上下文,保持页面样式、导航一致 context = dict( self.each_context(request), # 此处添加你的自定义上下文参数 ) return TemplateResponse(request, "admin/my_view.html", context) admin_site = MyAdminSite(name='my_admin') # 执行自动发现,加载所有应用的admin注册配置 admin.autodiscover() # 同步默认站点的所有模型注册到自定义站点 for model, model_admin in default_site._registry.items(): admin_site.register(model, model_admin.__class__)
方案2:更简单的实现(无需自定义AdminSite)
如果你的需求仅为添加1~N个自定义admin视图,完全不需要重写AdminSite,直接给默认admin站点追加URL即可,无需处理模型注册问题,代码量更少:
- 在任意应用的
admin.py中添加如下代码:
from django.contrib import admin from django.template.response import TemplateResponse from django.urls import path def my_view(request): # 继承admin全局上下文,保持页面样式、导航一致 context = dict( admin.site.each_context(request), # 此处添加你的自定义上下文参数 ) return TemplateResponse(request, "admin/my_view.html", context) # 给默认admin站点追加自定义URL admin.site.add_urls([ # admin_view自带权限校验,和其他admin页面规则一致 path('my-view', admin.site.admin_view(my_view), name='my-view'), ])
- 项目
urls.py保持默认admin配置即可,无需修改:
from django.contrib import admin urlpatterns = [ path('admin/', admin.site.urls), # 其他URL配置 ]
该方案实现的访问路径依然是/admin/my-view,和默认admin的权限、样式完全一致,原有模型注册不受任何影响。
内容的提问来源于stack exchange,提问作者dfrankow
相关产品推荐
相关产品推荐

