简体   繁体   中英

Reorder app and models in Django admin

I want to reorder my apps in my Django admin panel, I saw some responses from another similar question here in SO, so I go for install this method: django-modeladmin-reorder

I follow all the steps and it's not working. Here's my actual Django panel

在此处输入图像描述

#settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    # Disable Django's own staticfiles handling in favour of WhiteNoise, for
    # greater consistency between gunicorn and `./manage.py runserver`. See:
    # http://whitenoise.evans.io/en/stable/django.html#using-whitenoise-in-development
    'whitenoise.runserver_nostatic',
    'django.contrib.staticfiles',
    'admin_reorder',
    'organization_owners',
    'panel',
    'clients',
]

MIDDLEWARE_CLASSES = (
    'admin_reorder.middleware.ModelAdminReorder',
)


ADMIN_REORDER = (
    # Keep original label and models
    'organization_owners',
    'panel',
    'clients',
)

and also is in my requirements.txt

Django==2.0.1
django-extensions==1.9.8
django-modeladmin-reorder==0.2
djangorestframework==3.7.7
flake8==3.5.0

I have checked their github repo and it was updated two months ago to support Django 2.0 but it's Python Package Index version 0.2 was last uploaded on 2016-09-08.

So there are chances that pip installation still installs the version that does not support Django 2.0

Note that the urlresolvers module was deprecated in Django 1.10 and removed in 2.0 (django-modeladmin-reorder still relies on urlresolvers)

What you can do:

  1. If you already know Django==1.8 try django-modeladmin-reorder on that first.

  2. Use their code at GitHub in your project. Here is the link of the latest commit. https://github.com/mishbahr/django-modeladmin-reorder/commit/f21929480c398c2628291d74af2f319421f651f3

If you're working with Django 2.0 you have to edit middleware.py with this commit . Even the repository has the support for Django 2.0, pip is stalling and older version (as @Dhaval Savalia said).

After that, this step:

Add the ModelAdminReorder to MIDDLEWARE_CLASSES:

MIDDLEWARE_CLASSES = (
    ...
    'admin_reorder.middleware.ModelAdminReorder',
    ...
)

Should be replaced by:

MIDDLEWARE = [ 
        ...
        'admin_reorder.middleware.ModelAdminReorder',
        ...
]

And that's all.

I recently wrote an article on this. It may help. We need to use the template tag to re-order the apps and models like below.

add below code in settings

from collections import OrderedDict

APP_ORDER = OrderedDict([
  ("app1", ["Model2", "Model1", "Model3"]),
  ("app2", ["Model2", "Model5", "Model3"]),
  ("app3", ["Model1", "Model6", "Model3"]),
]) 

add below template tags

from django import template
from django.conf import settings


register = template.Library()


def pop_and_get_app(apps, key, app_label):
    for index, app in enumerate(apps):
        if app[key] == app_label:
            obj = apps.pop(index)
            return obj
    return None

@register.filter
def sort_apps(apps):
    new_apps = []
    order = settings.APP_ORDER
    for app_label in order.keys():
        obj = pop_and_get_app(apps, "app_label", app_label)
        new_apps.append(obj) if obj else None
    apps = new_apps + apps
    for app in apps:
        models = app.get("models")
        app_label = app.get("app_label")
        new_models = []
        order_models = settings.APP_ORDER.get(app_label, [])
        for model in order_models:
            obj = pop_and_get_app(models, "object_name", model)
            new_models.append(obj) if obj else None
        models = new_models + models
        app["models"] = models
    return apps

Override the admin/index.html like below

{% for app in app_list|sort_apps %}

Ref:https://learnbatta.com/blog/how-to-re-order-apps-models-django/

project/admin.py

from django.contrib.admin import AdminSite

class MyAdminSite(AdminSite):
    site_header = 'My Site'
    index_title = ''

    def get_app_list(self, request):
        app_order = [
            'app_1',
            'app_2',
            'auth',
        ]
        app_order_dict = dict(zip(app_order, range(len(app_order))))
        app_list = list(self._build_app_dict(request).values())
        app_list.sort(key=lambda x: app_order_dict.get(x['app_label'], 0))
        for app in app_list:
            if app['app_label'] == 'app_1':
                model_order = [
                    'Model1 verbose name',
                    'Model2 verbose name',
                    'Model3 verbose name',
                ]
                model_order_dict = dict(zip(model_order, range(len(model_order))))
                app['models'].sort(key=lambda x: model_order_dict.get(x['name'], 0))
        return app_list

project/apps.py

from django.contrib.admin.apps import AdminConfig

class MyAdminConfig(AdminConfig):
    default_site = 'project.admin.MyAdminSite'

project/settings.py

INSTALLED_APPS = [
    'project.apps.MyAdminConfig',
    <instead of django.contrib.admin>
    ...

I followed anjaneyulubatta505 answer but it only changed the order in the index page to change the order in all admin pages override app_list.html not index.html

app the template tag from anjaneyulubatta505 answer in any app

from django import template
from django.conf import settings


register = template.Library()


def pop_and_get_app(apps, key, app_label):
    for index, app in enumerate(apps):
        if app[key] == app_label:
            obj = apps.pop(index)
            return obj
    return None

@register.filter
def sort_apps(apps):
    new_apps = []
    order = settings.APP_ORDER
    for app_label in order.keys():
        obj = pop_and_get_app(apps, "app_label", app_label)
        new_apps.append(obj) if obj else None
    apps = new_apps + apps
    for app in apps:
        models = app.get("models")
        app_label = app.get("app_label")
        new_models = []
        order_models = settings.APP_ORDER.get(app_label, [])
        for model in order_models:
            obj = pop_and_get_app(models, "object_name", model)
            new_models.append(obj) if obj else None
        models = new_models + models
        app["models"] = models
    return apps

and add the order in your settings.py

from collections import OrderedDict

APP_ORDER = OrderedDict([
  ("app1", ["Model2", "Model1", "Model3"]),
  ("app2", ["Model2", "Model5", "Model3"]),
  ("app3", ["Model1", "Model6", "Model3"]),
]) 

and this is my app_list.html

{% load i18n admin_tags %}

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

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

            {% if model.admin_url and show_changelinks %}
              {% if model.view_only %}
                <td><a href="{{ model.admin_url }}" class="viewlink">{% translate 'View' %}</a></td>
              {% else %}
                <td><a href="{{ model.admin_url }}" class="changelink">{% translate 'Change' %}</a></td>
              {% endif %}
            {% elif show_changelinks %}
              <td></td>
            {% endif %}
          </tr>
        {% endfor %}
      </table>
    </div>
  {% endfor %}
{% else %}
  <p>{% translate 'You don’t have permission to view or edit anything.' %}</p>
{% endif %}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM