如何使用自定义 AdminSite 类?

2022-01-25 00:00:00 python django django-admin

问题描述

实现我自己的 django.contrib.admin.sites.AdminSite 的最佳方式是什么?

Which is the best way to implement my own django.contrib.admin.sites.AdminSite?

实际上我在 django.contrib.admin.autodiscover 中注册 INSTALLED_APPS 时遇到问题.如果我在 urls.py 中使用我的自定义 AdminSite 类,则管理页面上没有显示任何应用程序.

Actually I get a problem with the registration of INSTALLED_APPS in django.contrib.admin.autodiscover. If I use my custom AdminSite class in urls.py, there were no apps displayed on the admin page.

我用一个小技巧解决了这个问题.我写了这个类:

I fixed this with a litte hack. I wrote this class:

from django.contrib.admin.sites import site as default_site

class AdminSiteRegistryFix( object ):
    '''
    This fix links the '_registry' property to the orginal AdminSites
    '_registry' property. This is necessary, because of the character of
    the admins 'autodiscover' function. Otherwise the admin site will say,
    that you havn't permission to edit anything.
    '''

    def _registry_getter(self):
        return default_site._registry

    def _registry_setter(self,value):
        default_site._registry = value

    _registry = property(_registry_getter, _registry_setter)

并像这样实现我的自定义 AdminSite:

And implement my custom AdminSite like this:

from wltrweb.hacks.django.admin import AdminSiteRegistryFix
from django.contrib.admin import AdminSite

class MyAdminSite( AdminSite, AdminSiteRegistryFix ):
    # do some magic
    pass        


site = MyAdminSite()

所以我可以将这个 site 用于 urls.py.

So I can use this site for urls.py.

有人知道更好的方法吗?因为我访问一个以下划线开头的 var,所以它只不过是一个 hack.我不喜欢黑客攻击.

Anyone knows a better way? Since I access a var starting with a underscore it is no more than a hack. I don't like hacks.

另一种方法是重写 django.contrib.admin.autodiscover 函数,但在这种情况下我会有多余的代码.

Another way would be to rewrite the django.contrib.admin.autodiscover function, but in this case I would have redundant code.


解决方案

引用自 https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#customizing-the-adminsite-class

但是,如果您想使用自定义行为设置自己的管理站点,您可以自由地将 AdminSite 子类化并覆盖或添加任何您喜欢的内容.然后,只需创建一个 AdminSite 子类的实例(与实例化任何其他 Python 类的方式相同),并用它注册您的模型和 ModelAdmin 子类,而不是使用默认值.

If you'd like to set up your own administrative site with custom behavior, however, you're free to subclass AdminSite and override or add anything you like. Then, simply create an instance of your AdminSite subclass (the same way you'd instantiate any other Python class), and register your models and ModelAdmin subclasses with it instead of using the default.

我想这是最明确的方法,但这也意味着您需要更改应用程序 admin.py 文件中的注册码.

I guess that is the most explicit approach, but it also means that you need to change the register code in your apps admin.py files.

在使用您自己的 AdminSite 实例时确实不需要使用自动发现,因为您可能会在 myproject.admin 模块中导入所有应用程序 admin.py 模块.

There is really no need to use autodiscover when using your own AdminSite instance since you will likely be importing all the per-app admin.py modules in your myproject.admin module.

假设似乎是,一旦您开始编写您的自定义管理站点,它就会变得非常具体,并且您事先知道要包含哪些应用程序.

The assumption seems to be, that once you start writing your custom admin site, it becomes pretty much project specific and you know beforehand which apps you want to include.

因此,如果您不想使用上面的 hack,我只看到这两个选项.替换对您的自定义管理站点的所有注册调用,或在您的管理站点模块中显式注册模型.

So if you don't want to work with the hack above, I only really see these two options. Replace all register calls to your custom admin site or register the models explicitly in your adminsite module.

相关文章