【问题标题】:Django (1.10) override AdminSiteDjango (1.10) 覆盖 AdminSite
【发布时间】:2017-02-26 15:44:27
【问题描述】:

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

我创建了继承自类的自定义类 MyAdminSite

from django.contrib.admin import AdminSite


class MyAdminSite(AdminSite):
    pass

然后在我的应用程序 urls.py 中添加:

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),
]

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

我尝试了三种将模型注册到我的自定义站点的方法:

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

通过这种方式模型注册到原始 AdminSite。

第二种方式:

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

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

最后一种方式:

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

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

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

【问题讨论】:

  • 如何将模型注册到自定义管理站点?
  • 您链接到的文档中的哪些内容让您认为这可行?
  • 文档站点只是一个例子,我知道还有一些我想要的东西。我也尝试了很多其他教程和其他方法,但没有一个有效。
  • Django 2.1 will have a hook 轻松覆盖默认管理站点。

标签: python django


【解决方案1】:

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

首先我们需要在我们的应用程序中创建模块(例如 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

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

from .admin import site

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

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

@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)

这是唯一对我有用的解决方案。

【讨论】:

  • 这很有帮助!太糟糕了,我们必须竭尽全力扩展 AdminSite 并使其正常工作......
  • @icarovirtual 如此真实。我最终还是使用了这个答案,即使我需要做的只是向我的管理员的 index.html 页面添加 2 个额外的上下文变量
【解决方案2】:

来自 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
]

【讨论】:

    【解决方案3】:

    我遇到了类似的问题。我使用了上面 cmets 中的 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),
        ]
    

    这里的想法是从默认管理站点复制注册模型。也许这样做不好,但我找不到其他工作。

    【讨论】:

      猜你喜欢
      • 2017-07-13
      • 2011-10-30
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 2014-03-01
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多