在Django admin中重新排序应用和模型

xyhw6mcr  于 12个月前  发布在  Go
关注(0)|答案(6)|浏览(139)

我想在我的Django管理面板中重新排序我的应用程序,我在SO中看到了另一个类似问题的响应,所以我选择了安装这个方法:django-modeladmin-reorder
我遵循了所有的步骤,但它不起作用。


的数据

#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',
)

字符串
也在我的requirements.txt里

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

jtjikinw

jtjikinw1#

我已经检查了他们的github repo,它是两个月前更新的,以支持Django 2.0,但它的Python Package Index version 0.2最后一次上传是在2016-09-08。
因此,pip安装仍然有可能安装不支持Django 2.0的版本
请注意,urlresolvers模块在Django 1.10中被弃用,并在2.0中被删除(django-modeladmin-reorder仍然依赖于urlresolvers)
你可以做什么:
1.如果你已经知道Django==1.8,那么先试试django-modeladmin-reorder。
1.在你的项目中使用他们在GitHub上的代码。这里是最新提交的链接。https://github.com/mishbahr/django-modeladmin-reorder/commit/f21929480c398c2628291d74af2f319421f651f3

0g0grzrc

0g0grzrc2#

如果你正在使用Django 2.0,你必须用this commit编辑 middleware.py。即使仓库支持Django 2.0,pip也在拖延和旧版本(正如@Dhaval萨瓦利亚所说)。
然后,这一步:
将ModelAdminReorder添加到MIDDLEWARE_CLASSES:

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

字符串
应改为:

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


仅此而已

6jygbczu

6jygbczu3#

我遵循了anjaneyulubatta505 answer,但它只改变了索引页的顺序,以改变所有管理页的顺序,覆盖app_list.html而不是index.html
在任何应用程序中应用来自anjaneyulubatta505 answer的模板标签

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

字符串
并将订单添加到settings.py

from collections import OrderedDict

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


这是我的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 %}

vpfxa7rd

vpfxa7rd4#

我最近写了一篇关于这个的文章。它可能会有所帮助。我们需要使用模板标签来重新排序应用程序和模型,如下所示。

在设置中添加以下代码

from collections import OrderedDict

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

字符串

添加下面的模板标签

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

像下面这样删除admin/index.html

{% for app in app_list|sort_apps %}


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

nfeuvbwi

nfeuvbwi5#

项目/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

字符串
项目/apps.py

from django.contrib.admin.apps import AdminConfig

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


项目/settings.py

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

zazmityj

zazmityj6#

@tulsluper给出的回复正是我需要的,可以为我指出解决方案的方向,但是当我在管理面板中点击类别(应用名称)而不是模型时,它就死了。主屏幕可以工作,但是使用侧边栏向下钻到应用和模型却不行。我的第一次尝试也把面包屑弄砸了,这个答案解决了这个问题。
为了给予答案更多的价值,我离开了我的自定义“身份验证和授权”(我只是称之为帐户),其中包括用户和组(你必须重新注册组到自定义“用户”应用程序,让他们都在同一个应用程序)。
我还在这里留下了OAuth2应用程序的contrib版本,因为我可以看到在没有示例的情况下,您可能会遇到如何重新排序的问题。
如果你遗漏了任何东西,它仍然会存在于管理面板这样做,它只是没有得到修改。
由于Python重载是不可用的,所以我在那里设置了一个if来测试参数的可用性。如果没有这个分割,面包屑和应用程序的详细信息就会中断。在Django 4.2.4中,在主管理屏幕上,在侧边栏和面包屑中,一切似乎都工作得很好(并命令应用程序和模型)。
下面是我的project/admin.py程序的工作版本:

from django.contrib.admin import AdminSite

class CustomAdminSite(AdminSite):
    site_header = 'My Header'   # default: "Django Administration"
    index_title = 'Index Title' # default: "Site administration"
    site_title = 'Site Title'   # default: "Django site admin"
    site_url = "https://www.MyKewlSite.com"

    # Override the admin presentation order of the apps and models

    def get_app_list(self, request, app_label=None):

        if not app_label:
            # The order of the apps is set here (use the app_label name):
            app_order = [
                'app1',
                'app2',
                'app3',
                'users',
                'oauth2_provider',
            ]
            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))
        else:
            # Everything is sorted alphabetically by app and within each app.
            app_dict = self._build_app_dict(request, app_label)
            app_list = sorted(app_dict.values(), key=lambda x: x["name"].lower())

        # Iterate down the app list and set the presentation order of the models:
        for app in app_list:
            if app['app_label'] == 'users':
                model_order = [
                    'Users',
                    'Groups',
                ]
                model_order_dict = dict(zip(model_order, range(len(model_order))))
                app['models'].sort(key=lambda x: model_order_dict.get(x['name'], 0))

            elif app['app_label'] == 'oauth2_provider':
                model_order = [
                    'Applications',
                    'Grants',
                    'Id tokens',
                    'Access tokens',
                    'Refresh tokens',
                ]
                model_order_dict = dict(zip(model_order, range(len(model_order))))
                app['models'].sort(key=lambda x: model_order_dict.get(x['name'], 0))

    
            elif app['app_label'] == 'app3':
                model_order = [
                    'Model 2',
                    'Model 3',
                    'Model 1',
                ]
                model_order_dict = dict(zip(model_order, range(len(model_order))))
                app['models'].sort(key=lambda x: model_order_dict.get(x['name'], 0))
    
            elif app['app_label'] == 'app1':
                model_order = [
                    'Model 1',
                    'Model 3',
                    'Model 2',
                ]
                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

字符串
你需要一个项目/apps.py(注意,我的项目被称为“admin_site”,所以你会看到,而不是“项目”在这里和设置。

from django.contrib.admin.apps import AdminConfig

class CustomAdminConfig(AdminConfig):
    default_site = 'admin_site.admin.CustomAdminSite'


您还需要编辑您的项目/settings.py,并将contrib.admin替换为我们上面创建的自定义admin版本:

INSTALLED_APPS = (
    # 'django.contrib.admin',   
    'admin_site.apps.CustomAdminConfig',


玩得开心-我有这个运行,所以即使它不是公认的答案,它工作得很好,它是这样解决我的项目。

相关问题