Set ordering of Apps and models in Django admin dashboard
Asked Answered
D

3

7

By default, the Django admin dashboard looks like this for me:

enter image description here

I want to change the ordering of models in Profile section, so by using codes from here and here I was able to change the ordering of model names in Django admin dashboard:

class MyAdminSite(admin.AdminSite):
    def get_app_list(self, request):
        """
        Return a sorted list of all the installed apps that have been
        registered in this site.
        """
        ordering = {
            "Users": 1,
            "Permissions": 2,
            "Activities": 3,
        }
        app_dict = self._build_app_dict(request)
        # a.sort(key=lambda x: b.index(x[0]))
        # Sort the apps alphabetically.
        app_list = sorted(app_dict.values(), key=lambda x: x['name'].lower())

        # Sort the models alphabetically within each app.
        for app in app_list:
            app['models'].sort(key=lambda x: ordering[x['name']])

        return app_list

mysite = MyAdminSite()
admin.site = mysite
sites.site = mysite

New look and feel:

enter image description here

But as you see, I have lost the AUTHENTICATION AND AUTHORIZATION section; What should I do to have all the sections and at the same time have my own custom ordering for Profile section?

Dolphin answered 6/10, 2019 at 9:59 Comment(1)
Same problem with #398663Perplexed
B
2

With the code below in settings.py, you can reorder and hide the apps including AUTHENTICATION AND AUTHORIZATION(auth) and models in admin pages. *I use Django 4.1.7 and you can see the original get_app_list() in GitHub and you can see my answer demonstrating how the code below works:

# "settings.py"

ADMIN_ORDERING = (
    ('app2', ('Model3', 'Model1', 'Model2')),
    ('auth', ('User', 'Group')),
    ('app1', ('Model2', 'Model3', 'Model1'))
)

from django.contrib import admin

def get_app_list(self, request, app_label=None):
    app_dict = self._build_app_dict(request, app_label)
    
    if not app_dict:
        return
        
    NEW_ADMIN_ORDERING = []
    if app_label:
        for ao in ADMIN_ORDERING:
            if ao[0] == app_label:
                NEW_ADMIN_ORDERING.append(ao)
                break
    
    if not app_label:
        for app_key in list(app_dict.keys()):
            if not any(app_key in ao_app for ao_app in ADMIN_ORDERING):
                app_dict.pop(app_key)
    
    app_list = sorted(
        app_dict.values(), 
        key=lambda x: [ao[0] for ao in ADMIN_ORDERING].index(x['app_label'])
    )
     
    for app, ao in zip(app_list, NEW_ADMIN_ORDERING or ADMIN_ORDERING):
        if app['app_label'] == ao[0]:
            for model in list(app['models']):
                if not model['object_name'] in ao[1]:
                    app['models'].remove(model)
        app['models'].sort(key=lambda x: ao[1].index(x['object_name']))
    return app_list

admin.AdminSite.get_app_list = get_app_list
Banlieue answered 15/5, 2023 at 9:44 Comment(1)
This worked seamlessly with my project apps and models, but I still did not figure out how to have the apps and models of external packages work as smoothly. For instance, I've tried to reorder django-admin-interface models named 'sites' and 'admin interface' (where sites and installed themes are stored respectively), but only the app labels showed in the admin panel. The models did not. Still working on it.Tedmund
K
1

What u can do is just override the get_app_list method.

def get_app_list(self, request):
    """
    Return a sorted list of all the installed apps that have been
    registered in this site.
    """
    # Retrieve the original list
    app_dict = self._build_app_dict(request)
    app_list = sorted(app_dict.values(), key=lambda x: x['name'].lower())

    # Sort the models customably within each app.
    for app in app_list:
        if app['app_label'] == 'auth':
            ordering = {
                'Users': 1,
                'Groups': 2
            }
            app['models'].sort(key=lambda x: ordering[x['name']])

    return app_list

admin.AdminSite.get_app_list = get_app_list
Kenlee answered 30/6, 2021 at 4:57 Comment(0)
M
0

Call get_app_list() with super first, like that:

class MyAdminSite(admin.AdminSite):
def get_app_list(self, request):
    all_list = super().get_app_list(request)
    # reorder the app list as you like
    return app_list


mysite = MyAdminSite()
admin.site = mysite
sites.site = mysite
Meadow answered 6/10, 2019 at 10:20 Comment(1)
all_list = super().get_app_list(request) is still returning only the Profile section and not all the apps and models.Dolphin

© 2022 - 2024 — McMap. All rights reserved.