Django(1.10)覆盖AdminSite

时间:2016-10-17 15:18:15

标签: python django

我尝试使用自己的自定义类覆盖AdminSite类。我按照django的文档中的教程:https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#customizing-adminsite但它没有用。具体来说,我想用自己的类覆盖原始的AdminSite,而不只是在我的项目中添加另一个管理站点。

我已经创建了继承自类

的自定义类MyAdminSite
Code

然后在我的app urls.py中添加:

from django.contrib.admin import AdminSite


class MyAdminSite(AdminSite):
    pass

它似乎有效,但管理员模型注册到了MyAdminSite的AdminSite。

我尝试了三种注册模型到我的自定义网站的方式:

from django.conf.urls import url, include
import django.contrib.admin as admin
from .admin_site import MyAdminSite

admin.site = MyAdminSite()
admin.autodiscover()


urlpatterns = [
    url(r'^', admin.site.urls),
]

这种模式已注册到原始AdminSite。

第二种方式:

@admin.register(Model)
class ModelAdmin(model.AdminModel):
...

这不起作用并导致异常。 ModelAdmin类不会传递给register方法。

最后一种方式:

@admin.site.register(Model):
class ModelAdmin(model.AdminModel):
...

这样可行,但在管理员网站上我只能看到我的模型而不是来自Django管理员(用户和组)的模型。

如何永久覆盖admin.site并将所有模型注册到MyAdminSite?

3 个答案:

答案 0 :(得分:8)

来自myapp / admin.py:

from django.contrib.auth.models import Group, User
from django.contrib.auth.admin import GroupAdmin, UserAdmin
from django.contrib.admin import AdminSite
from django.contrib import admin

from .models import MyModel #This is my app's model

# Custom admin site
class MyAdminSite(AdminSite):
    site_header = 'My Project Title'
    site_title  = 'My Project Title Administration'
    index_title = 'My Project Title Administration'
    # You can add on more attributes if you need 
    # Check out https://docs.djangoproject.com/en/1.11/ref/contrib/admin/#adminsite-objects

# Create admin_site object from MyAdminSite
admin_site = MyAdminSite(name='my_project_admin')

# Register the models
class MyModelAdmin(admin.ModelAdmin):
    list_display = ('id', 'description')

admin_site.register(MyModel, MyModelAdmin)

# Create and register all of your models
# ....

# This is the default Django Contrib Admin user / group object
# Add this if you need to edit the users / groups in your custom admin
admin_site.register(Group, GroupAdmin)
admin_site.register(User, UserAdmin)

来自myproject / urls.py

from django.conf.urls import url
from django.contrib import admin
from myapp.admin import admin_site ##! Important..Import your object (admin_site) instead of your class (MyAdminSite)

urlpatterns = [
    url(r'^admin/', admin_site.urls), #Now all /admin/ will go to our custom admin
]

答案 1 :(得分:4)

我没有找到问题的解决方案,但我已经解决了。

首先我们需要在我们的应用程序中创建模块(例如admin.py),然后扩展类AdminSite:

from django.contrib.admin import AdminSite

class MyAdminSite(AdminSite):
    ...

然后在模块底部我们需要创建MyAdminSite的实例并从Django注册内置模型:

site = MyAdminSite()
site.register(Group, GroupAdmin)
site.register(User, UserAdmin)

必要的进口:

from django.contrib.auth.models import Group, User
from django.contrib.auth.admin import GroupAdmin, UserAdmin

在我们的网站网址模块中,我们需要覆盖原始网站对象:

from .admin import site

admin.site = site
admin.autodiscover()
...
url(r'^admin/', admin.site.urls)
...

我们需要做的最后一项更改是注册我们的模型。我们需要记住的一件事是我们不能像这样使用寄存器作为装饰器:

@admin.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    ...

或:

@admin.site.register(MyModel)
class MyModelAdmin(admin.ModelAdmin):
    ...

我们需要定义ModelAdmin类,然后在MyAdminSite对象上调用register:

class MyModelAdmin(admin.ModelAdmin):
    ...
admin.site.register(MyModel, MyModelAdmin

这是唯一适合我的解决方案。

答案 2 :(得分:0)

我遇到了类似的问题。我使用上面注释中的Django 2.1和the hook对我不起作用。而且我也无法像这样导入GroupAdmin和UserAdmin

from django.contrib.auth.models import Group, User
from django.contrib.auth.admin import GroupAdmin, UserAdmin

导入GroupAdmin或UserAdmin出于某些原因破坏了代码。我无法确定确切原因。

所以我的解决方法是(在project/urls.py中):

from django.conf.urls import include, url
from django.contrib.admin import site
from project.admin import myadmin

myadmin._registry.update(site._registry)

urlpatterns = [
    url(r'^admin/', myadmin.urls),
    ]

这里的想法是从默认管理站点复制注册的模型。这样做可能不好,但我找不到其他有效的方法。