You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

开发环境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类,根据环境动态调整显示的模型列表。

实现代码

  1. 先创建自定义的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')
  1. urls.py中替换默认的Admin路由:
from django.urls import path
from .admin import custom_admin_site

urlpatterns = [
    # 替换原来的admin.site.urls
    path('admin/', custom_admin_site.urls),
]
  1. 注册模型时使用自定义的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

火山引擎 最新活动