订购admin.ModelAdmin对象

Rui*_*ira 34 django django-admin

假设我有我的披萨应用程序与Topping和Pizza课程,他们在Django Admin中显示如下:

PizzaApp
-
Toppings      >>>>>>>>>>      Add / Change

Pizzas        >>>>>>>>>>      Add / Change
Run Code Online (Sandbox Code Playgroud)

但我希望他们这样:

PizzaApp
-
Pizzas        >>>>>>>>>>      Add / Change

Toppings      >>>>>>>>>>      Add / Change
Run Code Online (Sandbox Code Playgroud)

如何在我的admin.py中配置它?

小智 33

您可以尝试的解决方法是调整models.py,如下所示:

class Topping(models.Model):
    .
    .
    .
    class Meta:
        verbose_name_plural = "2. Toppings"

class Pizza(models.Model):
    .
    .
    .
    class Meta:
        verbose_name_plural = "1. Pizzas"
Run Code Online (Sandbox Code Playgroud)

不确定它是否违反了django的最佳实践,但它有效(用django trunk测试).

祝好运!

PS:对不起,如果这个答案发布得太晚,但在未来的类似情况下可以帮助其他人.

  • 伤心.如果你有3个披萨条目,它会说"3 1. Pizzas". (5认同)

Emm*_*uel 19

我最终设法做到这一点,感谢这个Django片段,你只需要知道这个ADMIN_REORDER设置:

ADMIN_REORDER = (
    ('app1', ('App1Model1', 'App1Model2', 'App1Model3')),
    ('app2', ('App2Model1', 'App2Model2')),
)
Run Code Online (Sandbox Code Playgroud)

app1不得以项目名称为前缀,即使用app1而不是mysite.app1.

  • 灵感来自我编写的代码片段https://github.com/mishbahr/django-modeladmin-reorder (7认同)
  • 可能不清楚的是,您需要整个片段,而不仅仅是此答案中发布的代码块。 (3认同)

小智 18

如果要在10秒内解决此问题,只需在verbose_name_plural中使用空格,例如:

class Topping(models.Model):
    class Meta:
        verbose_name_plural = "  Toppings" # 2 spaces

class Pizza(models.Model):
    class Meta:
        verbose_name_plural = " Pizzas" # 1 space
Run Code Online (Sandbox Code Playgroud)

当然,它不是优雅的,但在我们获得更好的解决方案之前可能会工作一段时间.

  • 超级简陋,但绝对是最快和最脏的! (3认同)

Dav*_*per 10

这实际上涵盖在Django教程第2部分的最底部.

这是相关部分:

自定义管理员索引页面

在类似的说明中,您可能希望自定义Django管理员索引页面的外观.

默认情况下,它按字母顺序显示已在管理应用程序中注册的INSTALLED_APPS中的所有应用程序.您可能希望对布局进行重大更改.毕竟,索引可能是管理员最重要的页面,它应该很容易使用.

要自定义的模板是admin/index.html.(与上一节中的admin/base_site.html相同 - 将其从默认目录复制到自定义模板目录.)编辑文件,您将看到它使用名为app_list的模板变量.该变量包含每个已安装的Django应用程序.您可以以您认为最好的方式将链接硬编码到特定于对象的管理页面,而不是使用它.

  • 这很有用,但我认为这个问题与同一个已安装应用中的几个Model类有关.如果您想在单个应用程序中更改Model类的顺序,更改应用程序的顺序将无济于事. (8认同)

Ric*_*era 6

以下是Emmanuel使用的片段,为Django 1.8更新:

在templatetags/admin_reorder.py中:

from django import template
from django.conf import settings
from collections import OrderedDict

register = template.Library()

# from http://www.djangosnippets.org/snippets/1937/
def register_render_tag(renderer):
    """
    Decorator that creates a template tag using the given renderer as the 
    render function for the template tag node - the render function takes two 
    arguments - the template context and the tag token
    """
    def tag(parser, token):
        class TagNode(template.Node):
            def render(self, context):
                return renderer(context, token)
        return TagNode()
    for copy_attr in ("__dict__", "__doc__", "__name__"):
        setattr(tag, copy_attr, getattr(renderer, copy_attr))
    return register.tag(tag)

@register_render_tag
def admin_reorder(context, token):
    """
    Called in admin/base_site.html template override and applies custom ordering
    of apps/models defined by settings.ADMIN_REORDER
    """
    # sort key function - use index of item in order if exists, otherwise item
    sort = lambda order, item: (order.index(item), "") if item in order else (
        len(order), item)
    if "app_list" in context:
        # sort the app list
        order = OrderedDict(settings.ADMIN_REORDER)
        context["app_list"].sort(key=lambda app: sort(order.keys(),
            app["app_url"].strip("/").split("/")[-1]))
        for i, app in enumerate(context["app_list"]):
            # sort the model list for each app
            app_name = app["app_url"].strip("/").split("/")[-1]
            if not app_name:
                app_name = app["name"].lower()
            model_order = [m.lower() for m in order.get(app_name, [])]
            context["app_list"][i]["models"].sort(key=lambda model:
            sort(model_order, model["admin_url"].strip("/").split("/")[-1]))
    return ""
Run Code Online (Sandbox Code Playgroud)

在settings.py中:

ADMIN_REORDER = (
    ('app1', ('App1Model1', 'App1Model2', 'App1Model3')),
    ('app2', ('App2Model1', 'App2Model2')),
)
Run Code Online (Sandbox Code Playgroud)

(在此处插入您自己的应用名称.管理员会在列表末尾放置缺少的应用或模型,只要您在每个应用中列出至少两个模型.)

在您的base_site.html副本中:

{% extends "admin/base.html" %}
{% load i18n admin_reorder %}

{% block title %}{{ title }} | {% trans 'Django site admin' %}{% endblock %}

{% block branding %}
{% admin_reorder %}
<h1 id="site-name">{% trans 'Django administration' %}</h1>
{% endblock %}

{% block nav-global %}{% endblock %}
Run Code Online (Sandbox Code Playgroud)


林伟雄*_*林伟雄 5

在2018年6月回答

这个答案类似于Vasil的想法

我试图解决类似的问题,然后看到了这样的片段

我根据此剪辑进行了一些修改。代码如下。

# myproject/setting.py
...
# set my ordering list
ADMIN_ORDERING = [
    ('pizza_app', [
        'Pizzas',
        'Toppings'
    ]),
]
# Creating a sort function
def get_app_list(self, request):
    app_dict = self._build_app_dict(request)
    for app_name, object_list in ADMIN_ORDERING:
        app = app_dict[app_name]
        app['models'].sort(key=lambda x: object_list.index(x['object_name']))
        yield app


# Covering django.contrib.admin.AdminSite.get_app_list
from django.contrib import admin

admin.AdminSite.get_app_list = get_app_list
...
Run Code Online (Sandbox Code Playgroud)

请注意,此排序功能中使用的排序列表包含系统中所有应用及其模块的排序。如果不需要,请根据自己的需要设计排序功能。

在Django 2.0上效果很好

  • 这是最简单、更优雅的解决方案!做得好。 (2认同)