0

I am trying to create a customised django-admin, with a separate page that is referenced in the app_list.

I have used https://stackoverflow.com/a/70446680 as a basis and can obtain the custom admin page. However, when I return to the admin home, all of the apps in the app_list are lost except the custom one.

I can remedy this by setting admin_urls = admin.site.get_urls() but when I do, my custom admin site no longer has a get_app_list method defined (from https://stackoverflow.com/a/56476261), so my app_list in admin, does not show the 'tcptraceroute' app.

from django.contrib.admin import AdminSite

class CustomAdminSite(AdminSite):

    def get_urls(self):
        admin_urls = super().get_urls() 
        print(admin_urls)
        custom_urls = [
            path('preferences/', views.my_view()),
        ]
        return custom_urls + admin_urls # custom urls must be at the beginning

    def get(self):
        request.current_app == self.name
        return super().get(request)

    def get_app_list(self, request):
        app_list = super().get_app_list(request)
        app_list += [
            {
                "name": "My Custom App",
                "app_label": "my_test_app",
                # "app_url": "/admin/test_view",
                "models": [
                    {
                        "name": "tcptraceroute",
                        "object_name": tcptraceroute,
                        "admin_url": "/admin/test_view",
                        "view_only": True,
                    }
                ],
            }
        ]
        return app_list

site = CustomAdminSite()

I have tried rearranging my app orders in installed apps, and also my urls, which currently load the customadmin site as per:

path('admin/', custom_admin.site.urls),

It seems that the currently defined admin site class is not accessible via the super() method, in the subclass. And when I call admin.site.get_urls() in the sub class, the super class no longer has a get_app_list method.

?

MTIA.

miller the gorilla
  • 860
  • 1
  • 7
  • 19

1 Answers1

0

I discovered that if I set the registry of the custom admin class to the registry of the admin.site then it would work as expected.

Code becomes...

In admin.py

from django.contrib import admin
from django.urls import path

from . import views

class CustomAdminSite(admin.AdminSite):
    
    def get_urls(self):
        self._registry = admin.site._registry
        admin_urls = super().get_urls() 
        custom_urls = [
            path('preferences/', views.Preferences.as_view(admin=self), name="preferences"),
        ]
        return custom_urls + admin_urls # custom urls must be at the beginning

    def get(self):
        request.current_app == self.name
        return super().get(request)

    def get_app_list(self, request):
        app_list = super().get_app_list(request)
        app_list += [
            {
                "name": "My Custom Preferences App",
                "app_label": "Preferences",
                # "app_url": "/admin/test_view",
                "models": [
                    {
                        "name": "Preferences",
                        "object_name": "preferences",
                        "admin_url": "/admin/preferences",
                        "view_only": True,
                    }
                ],
            }
        ]
        return app_list

site = CustomAdminSite()

the view...

class Preferences(views.generic.ListView):
    admin = {}
    def get(self, request):
        ctx = self.admin.each_context(request)
        return render(request, 'admin/preferences/preferences.html', ctx)

the template...

{% extends "admin/base_site.html" %}
{% block content %}
...HELLO WORLD!
{% endblock %}
miller the gorilla
  • 860
  • 1
  • 7
  • 19