django admin, extending admin with custom views

前端 未结 4 1481
花落未央
花落未央 2021-02-07 13:06

I would like to request some assistance regarding this matter.

I have followed this guide to add a view to my admin.

I am using the same code that the site has a

相关标签:
4条回答
  • 2021-02-07 13:38

    This guide looks quite old. I would rather advise you to follow django docs.

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

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

    You should also update your project/urls.py and replace path('admin/', admin.site.urls) by path('admin/', admin_site.urls). Don't forget to from someapp.admin import admin_site before.

    0 讨论(0)
  • 2021-02-07 13:39

    This code below will override the default admin site to write your custom view.

    Works for 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'
        ...
    ]
    

    Then go to http://127.0.0.1:8000/admin/my_view/

    0 讨论(0)
  • 2021-02-07 13:42

    The guide you linked is old and I was surprised to not find anything directly answering your question in the last year or so.

    1. Create a new Admin Site in your app's admin.py or in a convenient place.
    2. Create a function in the new AdminSite that augments the get_urls() function with your extra urls.
    3. Make sure your project urls.py links to the newly created AdminSite.

    The below works with Python 3.5.1 and 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),
        ...
    ]
    
    0 讨论(0)
  • 2021-02-07 13:48

    For Django 1.4+ here is the solution:

    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)
    

    It's important to append your custom URL before all others. Otherwise you might get redirect to admin change_view instead.

    0 讨论(0)
提交回复
热议问题