开发环境Django Admin显示全部模型,生产环境自动隐藏的实现方案
解决Django开发/生产环境Admin模型显示差异的方案
这个需求其实挺常见的,我自己开发Django项目时也经常遇到,分享几个靠谱的实现方式,既能在开发环境方便查看所有模型,又能保证生产环境的安全性:
方法一:基于DEBUG状态批量注册所有模型
利用Django的settings.DEBUG区分环境,在开发环境自动遍历所有已安装App的模型并注册,生产环境则不执行批量注册(只手动注册需要开放的模型)。
实现代码
在项目根目录的admin.py(或者专门的dev_admin.py再导入)中添加以下代码:
from django.contrib import admin from django.apps import apps from django.conf import settings from django.contrib.admin.exceptions import AlreadyRegistered # 可以自定义排除不想在开发环境显示的模型 EXCLUDE_MODELS = [ # 比如排除Django自带的用户、组模型(如果已经默认注册过) 'auth.User', 'auth.Group', ] def register_all_dev_models(): # 获取所有已安装App的模型 for model in apps.get_models(): # 跳过排除列表中的模型 model_label = f"{model._meta.app_label}.{model._meta.model_name}" if model_label in EXCLUDE_MODELS: continue try: admin.site.register(model) except AlreadyRegistered: # 模型已经被注册过(比如手动注册过),跳过即可 pass # 仅在DEBUG模式(开发环境)执行批量注册 if settings.DEBUG: register_all_dev_models()
这样一来,开发环境下所有未被排除的模型都会自动出现在Admin面板,生产环境则只会显示你手动注册的模型(如果有的话)。
方法二:自定义AdminSite控制模型显示
如果需要更精细的控制(比如生产环境只开放特定模型,开发环境开放全部),可以自定义AdminSite类,根据环境动态调整显示的模型列表。
实现代码
- 先创建自定义的AdminSite:
# admin.py from django.contrib.admin import AdminSite from django.conf import settings class CustomAdminSite(AdminSite): site_header = "项目管理后台" def get_app_list(self, request): app_list = super().get_app_list(request) if not settings.DEBUG: # 生产环境只保留指定的App和模型 allowed_apps = ['myapp'] # 替换成你需要开放的App名称 allowed_models = ['myapp.MyModel1', 'myapp.MyModel2'] # 替换成需要开放的模型 filtered_apps = [] for app in app_list: if app['app_label'] not in allowed_apps: continue # 过滤模型 app['models'] = [ model for model in app['models'] if f"{app['app_label']}.{model['object_name']}" in allowed_models ] if app['models']: filtered_apps.append(app) return filtered_apps # 开发环境返回全部模型 return app_list # 实例化自定义AdminSite custom_admin_site = CustomAdminSite(name='custom_admin')
- 在
urls.py中替换默认的Admin路由:
from django.urls import path from .admin import custom_admin_site urlpatterns = [ # 替换原来的admin.site.urls path('admin/', custom_admin_site.urls), ]
- 注册模型时使用自定义的AdminSite:
# 在各个App的admin.py中 from myproject.admin import custom_admin_site from .models import MyModel1, MyModel2 # 不管环境都注册,但生产环境会被过滤掉 custom_admin_site.register(MyModel1) custom_admin_site.register(MyModel2)
这种方式灵活性更高,能精准控制生产环境显示的内容,同时开发环境自动显示所有已注册的模型。
方法三:条件注册单个模型
如果只需要针对个别模型做环境控制,可以用条件语句包裹注册代码:
from django.contrib import admin from django.conf import settings from .models import MyDevOnlyModel # 仅在开发环境注册该模型 if settings.DEBUG: admin.site.register(MyDevOnlyModel)
这种方式适合零散的模型,批量场景还是前两种方法更高效。
内容的提问来源于stack exchange,提问作者Y2H




