Custom Ordering and Grouping of Models in Django Admin

3,691 views
Skip to first unread message

Vasanth Mohan

unread,
Sep 16, 2021, 1:45:59 PM9/16/21
to Django developers (Contributions to Django itself)
As the numbers Models in an app grows, it becomes tedious to find the model we are searching for in a long list on the index page (and navigation bar) of the Django admin

As a part of a new project, I wanted to reorder and logically group models that do not necessarily reflect the apps of the project. I found this little library called [django-modeladmin-reorder](https://github.com/mishbahr/django-modeladmin-reorder) that does it by remapping the fields with a middleware.

However, I think it would be cleaner if Django supported it natively as this can be useful in almost every project. A layer called AdminApp between the `admin` and the ModelAdmin registered would be the perfect middle ground.

**Proposal**

- Create a new class in admin called `AdminApp`
    - The AdminApp should be registerable to admin
    - The AdminApp should accept ModelAdmin to be registered with it
- Wire up the ModelAdmins and AdminApps to see custom layout that is not tied to apps
- For all ModelAdmins registered directly to admin, fallback to current implementation

```
class AgencyAdmin(admin.ModelAdmin):
   pass

class AgencyConfigAdmin(admin.ModelAdmin):
   pass

class AgencyAdminApp(admin.AdminApp):
   label = "Agency Details"

class AgentAdmin(admin.ModelAdmin):
   pass


admin.register(AgentAdmin) # Existing implementation

# Option 1 : without decorators
## Add Models to AdminApp
AgencyAdminApp.register(AgencyAdmin)
AgencyAdminApp.register(AgencyConfigAdmin)
## Add New AdminApp tp Admin
admin.register_app(AgencyAdminApp)

# Option 2 : with decorators
admin.register(AgencyAdmin, admin_app=AgencyAdminApp)
admin.register(AgencyConfigAdmin, admin_app=AgencyAdminApp)
```

I feel like this seems like a decent middle ground that doesn't break existing implementation but allows the app to be expanded in the future.

So what do you think about the idea? If the core team is interested, I'll be more than willing to work on this but I am first time contributor and will need some mentoring on it.

 I've also made a forum post for the same : https://forum.djangoproject.com/t/custom-admin-apps-for-grouping-and-reordering-models/9723

Mariusz Felisiak

unread,
Sep 16, 2021, 2:39:33 PM9/16/21
to Django developers (Contributions to Django itself)
Hi,

    Thanks for the proposition. It was discussed few times in the past. AdminSite.get_app_list() could be used to re-arrange models and apps, see ticket-5986 and its duplicates ticket-25671 and ticket-32482. Feel-free to prepare a patch.

Best,
Mariusz

Jacob Rief

unread,
Jun 16, 2022, 10:25:48 AM6/16/22
to Django developers (Contributions to Django itself)
Hi,
just encountered this same problem today.
As Roman reported in ticket-32484:

Sometimes model names are so unfortunate that default alphabetical order of models in contrib.admin application makes no sense at all.
The same applies to applications themselves. When there are many applications or many models within application there is a natural need to group them up logically.

Reordering of models is covered in many online resources, but the very process is so inconsistent and complex, that few get it right.

I would like to propose the following solution:

We add a new method order_models (or sort_models) to class admin.AdminSite. This method then sorts the models according to its own
logic and defaults to models.sort(key=lambda x: x["name"]). Whenever someone wants to sort his models otherwise, he just has to
override this method. This new method then is called by AdminSite.get_app_list and AdminSite.app_index.

The alternative I had to use today, was to override both methods, get_app_list and app_index to override just the model sorting part –
I therefore had to copy & paste 30 lines of Django code to replace just one function!

It btw. is much DRYer to implement the sorting of something into an external overridable method, rather than implementing this twice, as in both
methods just mentioned.

If the named ticket is reopened, I will implement this.

– Jacob

Mariusz Felisiak

unread,
Jun 16, 2022, 1:20:23 PM6/16/22
to Django developers (Contributions to Django itself)
Hi Jacob,

    It's already solved in Django 4.1+ by https://github.com/django/django/commit/2bee0b4328319eaf6a0d1686677d629f2ecf6dec. You can now override get_app_list() to change the default order on the admin index page. See docs.

Best,
Mariusz

Jacob Rief

unread,
Jun 17, 2022, 6:36:26 AM6/17/22
to Django developers (Contributions to Django itself)
Hi Mariusz,

On Thursday, June 16, 2022 at 7:20:23 PM UTC+2 Mariusz Felisiak wrote:
    It's already solved in Django 4.1+ by https://github.com/django/django/commit/2bee0b4328319eaf6a0d1686677d629f2ecf6dec. You can now override get_app_list() to change the default order on the admin index page. See docs.

Thanks and ups, apparently I missed that.
This indeed makes life much easier, because now I only have to override method AdminSite.get_app_list which is much shorter.
– Jacob
 
Reply all
Reply to author
Forward
0 new messages