当前位置:  开发笔记 > 编程语言 > 正文

订购admin.ModelAdmin对象

如何解决《订购admin.ModelAdmin对象》经验,为你挑选了7个好方法。

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

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

Pizzas        >>>>>>>>>>      Add / Change

但我希望他们这样:

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

Toppings      >>>>>>>>>>      Add / Change

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



1> 小智..:

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

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

class Pizza(models.Model):
    .
    .
    .
    class Meta:
        verbose_name_plural = "1. Pizzas"

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

祝好运!

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


伤心.如果你有3个披萨条目,它会说"3 1. Pizzas".

2> Emmanuel..:

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

ADMIN_REORDER = (
    ('app1', ('App1Model1', 'App1Model2', 'App1Model3')),
    ('app2', ('App2Model1', 'App2Model2')),
)

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


灵感来自我编写的代码片段https://github.com/mishbahr/django-modeladmin-reorder

3> 小智..:

如果要在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

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



4> Jdruiter..:

现在有一个很好的Django包:

https://pypi.python.org/pypi/django-modeladmin-reorder



5> Dave Kasper..:

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

这是相关部分:

自定义管理员索引页面

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

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

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


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

6> Rick Westera..:

以下是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 ""

在settings.py中:

ADMIN_REORDER = (
    ('app1', ('App1Model1', 'App1Model2', 'App1Model3')),
    ('app2', ('App2Model1', 'App2Model2')),
)

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

在您的base_site.html副本中:

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

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

{% block branding %}
{% admin_reorder %}

{% trans 'Django administration' %}

{% endblock %} {% block nav-global %}{% endblock %}



7> 林伟雄..:

在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
...

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

在Django 2.0上效果很好

推荐阅读
手机用户2402851335
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有