通过AdminSite.get_urls添加非基于模型的URL无效

时间:2015-08-10 19:12:05

标签: python django

我尝试使用get_urls成员函数将非基于模型的URL添加到管理页面:

from django.contrib.admin.sites import AdminSite
from django.conf.urls import url
from myapp.models import Bar

class StaffAdmin(AdminSite):
    site_header = 'My App'
    site_title = site_header
    def get_urls(self):
        urls = super(StaffAdmin, self).get_urls()
        my_urls = [
            url(r'^foo/$', self.foo_view, name='foo'),
        ]
        return my_urls + urls
    def foo_view(self, request):
        context = dict(
            self.admin_site.each_context(request),
            key=value,
        )
        return TemplateResponse(request, 'foo_view.html', context)

staff_admin_site = StaffAdmin()
staff_admin_site.register(Bar)

Bar在人员管理页面上显示OK,但foo缺失。

参考:https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_urls

3 个答案:

答案 0 :(得分:1)

在 Django >= 3.2 中,您的自定义管理网址应位于网址的顶部(在 catch_all_view 之前),否则您将从 django.contrib.admin.sites.catch_all_view

获得 404
class StaffAdmin(AdminSite):
    def get_urls(self):
        my_urls = [
            url(r'^foo/$', lambda request: HttpResponse('Foo'), name='foo'),
        ]
        urls = super().get_urls()
        return my_urls + urls

或者您可以将 AdminSite.final_catch_all_view 设置为 False 但为 not recommended

答案 1 :(得分:0)

您从文档中复制的foo_view代码只是一个示例,它不会开箱即用。

但是,使用工作视图(在本例中使用简单的lambda)可以正常工作:

class StaffAdmin(AdminSite):
    def get_urls(self):
        urls = super(AdminSite, self).get_urls()
        my_urls = [
            url(r'^foo/$', lambda request: HttpResponse('Foo'), name='foo'),
        ]
        return my_urls + urls

在浏览器中访问/admin/foo/会显示字符串'Foo'(如果您没有使用管理员前缀删除或使用您自己的路径更改它)

我假设您在管理索引页面中出现了一个神奇地出现的链接。无论多么方便,索引模板都不会知道您的自定义网址,因此您必须覆盖模板才能添加它们。

More about custom admin links

答案 2 :(得分:0)

我找到了使用以下步骤在管理面板上创建自定义链接问题的解决方案:

从模型中创建代理模型:

from myapp.models import Foo

class FooProxy(Foo):
    class Meta:
        proxy = True

注册代理模型:

admin.site.register(FooProxy)

覆盖urls.py中的管理员URL(通过在管理模式之前放置相关模式):

urlpatterns = [
    url(r'^admin/myapp/fooproxy/$', FooView.as_view(), name='foo-view'),
    url(r'^admin/', include(admin.site.urls)),
    ...
]