使用自定义admin站点自动注册Django授权模型



我使用Django auth与默认的管理站点实现身份验证管理,但后来我想使用我自己的AdminSite重写一些行为:

class OptiAdmin(admin.AdminSite):
    site_title = "Optimizer site's admin"
    #...Other stuff here

然后注册了我自己的模型:

admin_site = OptiAdmin(name='opti_admin')
admin.site.register(MyModel, MyModelAdmin)
#Other stuff here

但是当我去管理网站时,我只能看到我刚刚注册的模型,这对我来说听起来很公平,但我想看到这个新的自定义网站中的所有其他应用程序模型,包括auth的用户和组,我不知道如何像默认管理员一样自动做到这一点,请帮助:)。

  1. 用一个简单的__init__()覆盖创建你自己的AdminSite
  2. urls.py中导入您的 admin。

替换Django Admin和获得autodiscover()行为是可能的最小的努力。下面是一个以典型django-admin startproject project方式生成的项目结构:

project/
    manage.py
    project/
        __init__.py
        settings.py
        urls.py
        wsgi.py
        admin.py  # CREATE THIS FILE

project/admin.py:(我认为在项目级别这样做最有意义。)

from django.contrib.admin import *  # PART 1
class MyAdminSite(AdminSite):
    site_header = "My Site"
    def __init__(self, *args, **kwargs):
        super(MyAdminSite, self).__init__(*args, **kwargs)
        self._registry.update(site._registry)  # PART 2
site = MyAdminSite()

项目/urls . py(片段):

from . import admin  # PART 3
urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

第1部分是简单的Python。通过将django.contrib.admin中的所有内容导入到您的名称空间中,它充当了一个临时替代品。我想你不必这么做,但这有助于保持期望。第3部分,简单地连接管理。第2部分是真正的技巧。正如文档所说,调用autodiscover()来完成这项工作。自动发现所做的只是通过INSTALLED_APPS尝试导入一个名为admin.py的文件。当然,导入会运行代码,这些代码会做与注册模型相同的事情(通过装饰器和方法进行示例)。没有魔法。不需要向自定义管理员注册模型(如文档所述)。

自动发现看起来比它的register_to kwarg更聪明。这表明您可以通过自己的管理调用autodiscover()。不;那里没有电线连接(未来的功能?)赋值在这里发生,并在这里固定到本地AdminSite实例(或在这里使用装饰器)。Django contrib模型注册到这个实例,任何第三方库也会注册到这个实例。它不是你能上钩的东西。

这里的技巧,_registry只是一个字典映射。让Django自动发现所有的东西,然后只需要复制映射。这就是self._registry.update(site._registry)工作的原因。"self"是你自定义的AdminSite实例,"site"是Django的实例,你可以在其中任意一个注册你的模型。

(最后注意:如果缺少模型,则是因为导入顺序。所有的注册到Django的AdminSite需要在你复制_registry之前完成。直接注册到您的自定义管理员可能是最简单的事情。

Django文档建议在自定义管理站点中使用SimpleAdminConfig

INSTALLED_APPS = (
    ...
    'django.contrib.admin.apps.SimpleAdminConfig',
    ...
)

防止模型被注册为默认的AdminSite

文档似乎假设您将单独导入模型并将它们添加到您的自定义管理站点:

from django.contrib.auth.models import Group, User
from django.contrib.auth.admin import GroupAdmin, UserAdmin
admin_site.register(Group, GroupAdmin)
admin_site.register(User, UserAdmin)

如果你在许多应用程序中都有模型,这将是非常重复的。它不提供任何建议如何自动注册模型从所有的应用程序到您的自定义站点。

你可以试着给admin打补丁,然后用你自己的admin.site替换。

from django.contrib import admin
admin.site = OptiAdmin(name='opti_admin')

然后,当代码调用admin.site.register()时,它将向管理站点注册模型。这段代码必须在注册任何模型之前运行。你可以试着把它放在AppConfig为您的应用程序,并确保您的应用程序在django.contrib.admin之上。

再加上JCotton的精彩回答:

使用django 2.0,覆盖site_headersite_title的自定义管理站点只适用于index页面。

要使它与所有管理视图一起工作,用以下代码扩展JCotton的代码:

    def __init__(self, *args, **kwargs):
        super(MyAdminSite, self).__init__(*args, **kwargs)
        self._registry.update(site._registry)  # PART 2
        for model, model_admin in self._registry.items():
            model_admin.admin_site = self

就像这样在你的CustomAdminSite类中包含init方法。

    class CustomAdminSite(admin.AdminSite):
        def __init__(self, *args, **kwargs):
            super(CustomAdminSite, self).__init__(*args, **kwargs)
            self._registry.update(admin.site._registry)

对于仍然遇到这个问题的人:

如果你定义了一个自定义的AdminSite,并在自定义的AdminConfig中配置它,你不需要为你自己的网站手动注册第三方模型/模型表单(参见Django实现,它如何使用这个来找到合适的AdminSite)

在您的示例中,现在您有了OptiAdmin,您需要定义如下内容:

# my_project.apps.py
from django.contrib.admin.apps import AdminConfig
class OptiAdminConfig(AdminConfig)
  default_site = 'my_project.admin.OptiAdmin'

然后,在settings.py文件中,您需要在INSTALLED_APPS配置中设置它,如下所示:

INSTALLED_APPS = [
    ...
    "my_project.apps.OptiAdminConfig",
    ...
]

现在你应该可以在Django管理站点中看到第三方应用注册的所有模型。

最新更新