Sort Apps in the Django Admin

The Problem

Django sorts applications in the admin panel in alphabetical order by default. The reality, however, is that users rarely need apps sorted this way.

I was working on a project recently where for the first time since working with Django, the admin users were not power users - and so they needed some extra guidance.

The Solution

I created a small template tag to solve this problem. It simply takes a list of your apps sorted correctly, and I use it in a slightly modified Django admin template.

Let's go! 🚀

1. Override the Django Admin Index:

Add yourapp/templates/admin/index.html to your project. Add the following content:

{% extends "admin/index.html" %}
{% block content %}
{% load i18n static sort_apps %}
<div id="content-main">

{% if app_list %}
    {% for app in app_list|sort_apps %}
        <div class="app-{{ app.app_label }} module">
        <table>
        <caption>
            <a href="{{ app.app_url }}" class="section" title="{% blocktrans with name=app.name %}Models in the {{ name }} application{% endblocktrans %}">{{ app.name }}</a>
        </caption>
        {% for model in app.models %}
            <tr class="model-{{ model.object_name|lower }}">
            {% if model.admin_url %}
                <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
            {% else %}
                <th scope="row">{{ model.name }}</th>
            {% endif %}

            {% if model.add_url %}
                <td><a href="{{ model.add_url }}" class="addlink">{% trans 'Add' %}</a></td>
            {% else %}
                <td>&nbsp;</td>
            {% endif %}

            {% if model.admin_url %}
                <td><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
            {% else %}
                <td>&nbsp;</td>
            {% endif %}
            </tr>
        {% endfor %}
        </table>
        </div>
    {% endfor %}
{% else %}
    <p>{% trans "You don't have permission to edit anything." %}</p>
{% endif %}
</div>
{% endblock %}

A few notes:

  • This is tested in Django 1.8 - 1.10. it may not work in other versions.
  • If the template is not working, ensure you have the correct template loaders or just move it to the directory you normally use to override Django admin apps.

2. Create the sort_apps TemplateTag

Create a new template tag. (your_app/templatetags/sort_apps.py) with the following code:

from django import template
from django.conf import settings
register = template.Library()

@register.filter
def sort_apps(apps):
    count = len(apps)
    apps.sort(
        key = lambda x:
            settings.APP_ORDER.index(x['app_label'])
            if x['app_label'] in settings.APP_ORDER
            else count
    )
    return apps

3. Add APP_ORDER to settings.py

Now, just simply add a new setting to your settings file. If your apps are already correctly ordered in your INSTALLED_APPS, you can just set APP_ORDER = INSTALLED_APPS. I don't recommend this, as sometimes the order of application loading matters.

The final setting should look something like this:

APP_ORDER = [
    'configuration',
    'users',
    'app1',
    'app2',
    'app_etc'
]

Now, visit the Django admin panel - you will find it correctly ordered!

Maybe one day I'll make a package for this...