Django管理后台,使用自定义视图扩展管理后台。

18

关于这件事,我想请求一些帮助。

我按照这个指南添加了一个视图到我的管理界面。

我正在使用该网站相同的代码,但是我遇到了一个错误:

Reverse for 'app_list' with arguments '()' and keyword arguments '{'app_label': 'reports'}' not found.

admin/my_view可以正常工作,但如果我尝试访问管理中的其他页面(例如索引页面),我会遇到这个错误。

以下是代码:

#someapp/admin.py

from django.conf.urls import patterns
from django.contrib import admin
from django.http import HttpResponse

def my_view(request):
    return HttpResponse("Hello!")

def get_admin_urls(urls):
    def get_urls():
        my_urls = patterns('',
            (r'^my_view/$', admin.site.admin_view(my_view))
         )
        return my_urls + urls
    return get_urls

admin_urls = get_admin_urls(admin.site.get_urls())
admin.site.get_urls = admin_urls

我使用的是django 1.8.2版本和python 2.7版本。

另外,如何在管理员首页添加一些视图或上下文最佳方式是什么?

更新

我尝试了Antoine Pinsard的答案并尝试了这个:

#admin.py
from django.contrib.admin import AdminSite
class MyAdminSite(AdminSite):

    def get_urls(self):
        from django.conf.urls import url
        urls = super(MyAdminSite, self).get_urls()
        urls += [
            url(r'^my_view/$', self.admin_view(self.my_view))
        ]
        return urls

    def my_view(self, request):
        return HttpResponse("Hello!")

admin_site = MyAdminSite()

将 urls.py 中的 url(r'^admin/', include(admin.site.urls)), 替换为 url(r'^admin/', include(admin_site.urls)),

并出现以下错误信息:

Reverse for 'app_list' with arguments '()' and keyword arguments

TRACEBACK:

Request Method: GET
Request URL: http://localhost:8000/@dmin/

Django Version: 1.8.2
Python Version: 2.7.10
Installed Applications:
('grappelli',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.sessions.models',
 'frontend',
 'file_maintenance',
 'reports',
 'transactions',
 'admin_reorder',
 'admin_notifications',
 'django_twilio',
 'daterange_filter')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.models.User',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'admin_reorder.middleware.ModelAdminReorder')


Traceback:
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
  157.                     response = middleware_method(request, response)
File "C:\Python27\lib\site-packages\admin_reorder\middleware.py" in process_template_response
  134.         self.init_config(request, app_list)
File "C:\Python27\lib\site-packages\admin_reorder\middleware.py" in init_config
  21.         admin_index = admin.site.index(request)
File "C:\Python27\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
  57.         response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\sites.py" in index
  438.                                 current_app=self.name,
File "C:\Python27\lib\site-packages\django\core\urlresolvers.py" in reverse
  579.     return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "C:\Python27\lib\site-packages\django\core\urlresolvers.py" in _reverse_with_prefix
  496.                              (lookup_view_s, args, kwargs, len(patterns), patterns))

Exception Type: NoReverseMatch at /@dmin/
Exception Value: Reverse for 'app_list' with arguments '()' and keyword arguments '{'app_label': 'django_twilio'}' not found. 0 pattern(s) tried: []

请提供完整的回溯信息。另外,请注意patterns已被弃用。您应该使用一个url列表。 - Antoine Pinsard
我已经更新了我的帖子。 - Juan Carlos Asuncion
如果有人仍然对此有疑问 - 您可以查看此帖子 https://dev59.com/xG445IYBdhLWcg3wZJiw。这有点棘手,但有助于不覆盖项目中的AdminSite实例。 - alexche8
我在 https://findwork.dev/blog/integrating-chartjs-django-admin/ 上详细介绍了如何扩展管理页面。 - danihodovic
4个回答

19

这篇指南看起来相当陈旧。我更愿意建议您遵循Django文档

someapp/admin.py

from django.contrib.admin import AdminSite
from django.http import HttpResponse

class MyAdminSite(AdminSite):

     def get_urls(self):
         from django.urls import path
         urls = super().get_urls()
         urls += [
             path('my_view/', self.admin_view(self.my_view))
         ]
         return urls

     def my_view(self, request):
         return HttpResponse("Hello!")

admin_site = MyAdminSite()

来源: https://github.com/django/django/blob/2.2/django/contrib/admin/sites.py#L194-L205

你还应该更新你的project/urls.py文件,将path('admin/', admin.site.urls)替换为path('admin/', admin_site.urls)。别忘了在此之前先执行from someapp.admin import admin_site


11

您提供的指南已经过时,我很惊讶地发现在过去一年左右的时间里没有找到任何直接回答您问题的内容。

  1. 在您应用程序的admin.py或方便的位置中创建一个新的Admin Site
  2. 在新的AdminSite中创建一个函数,增加get_urls()函数与您的额外URL。
  3. 确保项目的urls.py链接到新创建的AdminSite

以下适用于Python 3.5.1和Django 1.9.6。


my_app/admin.py

from django.contrib import admin
from django.contrib.admin import AdminSite
from django.http import HttpResponse

from my_app.models import SomeModel


class MyAdminSite(AdminSite):

    def custom_view(self, request):
        return HttpResponse("Test")

    def get_urls(self):
        from django.conf.urls import url
        urls = super(MyAdminSite, self).get_urls()
        urls += [
            url(r'^custom_view/$', self.admin_view(self.custom_view))
        ]
        return urls

admin_site = MyAdminSite()


@admin.register(SomeModel, site=admin_site)
class SomeModelAdmin(admin.ModelAdmin):
    pass

my_project/urls.py

from django.conf.urls import url, include

from my_app.admin import admin_site

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

赞同一个清晰且可行的示例。有没有想法如何使其适用于“多个”项目,而不仅仅是一个? - dKen
@dKen 我有点困惑。你是指多个 Django 项目吗?如果是的话,我不确定这是可能的。 - Daniel van Flymen
非常抱歉,我混淆了我的术语! 我的意思是要问如何使其与多个应用程序一起工作。 对于造成的困惑,我感到非常抱歉! - dKen
这个方法可以用于多个应用程序...你只需要将实例化的类导入到所有应用程序中:from common.admin import admin_site - Daniel van Flymen
这会使应用程序从管理员“主页”中消失 - 这是预期的行为吗? - zerohedge
显示剩余2条评论

1
对于Django 1.4+,这是解决方案:
from django.conf.urls import url
from django.contrib import admin
from .models import MyModel


class MyAdmin(admin.ModelAdmin):
    list_display = (...)

    def custom_admin_view(self, request):
        # your logic here
        if request.method == 'POST':
            ...
        else:
            ...
        return HttpResponse(...)

    def get_urls(self):
        additional_urls = [
            url(r'^custom/$', self.admin_site.admin_view(self.custom_admin_view), name='custom')
        ]
        # append your custom URL BEFORE default ones
        return additional_urls + super().get_urls()


admin.site.register(MyModel, MyAdmin)

在其他URL之前添加自定义URL非常重要。否则,您可能会被重定向到管理员的change_view页面。

0
以下代码将覆盖默认的管理站点以编写您的自定义视图。
适用于Django >= 2.1:

###myproject/admin.py

from django.contrib import admin
from django.http import HttpResponse

class MyAdminSite(admin.AdminSite):

    def my_view(self, request): # your custom view function
        return HttpResponse("Test")

    def get_urls(self):
        from django.urls import path

        urlpatterns = super().get_urls()
        urlpatterns += [
            path('my_view/', self.admin_view(self.my_view))
        ]
        return urlpatterns

###myproject/apps.py

from django.contrib.admin.apps import AdminConfig

class MyAdminConfig(AdminConfig):
    default_site = 'myproject.admin.MyAdminSite'

###myproject/settings.py

INSTALLED_APPS = [
    ...
    'myproject.apps.MyAdminConfig',  # replaces 'django.contrib.admin'
    ...
]

然后前往http://127.0.0.1:8000/admin/my_view/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接