2008-12-29 122 views
28

比方说,我有我的摘心和比萨类应用的比萨,它们显示了Django管理这样的:订购admin.ModelAdmin对象

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

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

但我想他们是这样的:

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

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

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

回答

11

这实际上是涵盖在Part 2 of the Django Tutorial最底部。

这里的相关章节:

定制管理索引页面

与此类似,您可能希望 定制 Django管理的索引页面的外观和感觉。

默认情况下,它会显示所有的应用程序中INSTALLED_APPS 已经被按照字母顺序 与管理应用程序注册, 。您可能想要 对 布局进行重大更改。毕竟这个指数是 可能是管理员最重要的一个网页 ,应该很容易 的使用。

要自定义的模板是 admin/index.html。 (一样做在前面 部分 管理/ base_site.html - 从默认 目录将自定义模板 目录复制),编辑文件,你会看到 它使用一种称为模板变量 app_list。该变量包含安装的每个Django应用程序的 。您可以使用 来代替 ,无论您认为哪种方式最好,您都可以在 中硬编码指向 对象特定管理页面的链接。

+3

这是很好的知道,但我认为这个问题涉及到相同的安装应用程序中的几个模型类。如果您想在单个应用程序中更改模型类的顺序,更改应用程序的顺序不会对您有所帮助。 – Jeff 2008-12-29 19:03:49

+0

这是很好的想法。他们必须在某处列出,也许我只需要在那里应用排序过滤器。我将在明天看到这个(欧洲时区...)谢谢 – 2008-12-29 20:01:55

0

这只是一个在黑暗中的野生刺伤,但是有没有什么机会让您称之为admin.site.register(< Model class>,< ModelAdmin class>)的顺序可以决定显示顺序?实际上,我怀疑这是否行得通,因为我相信Django会维护Model - > ModelAdmin对象的注册表,并将其作为标准Python字典实现,该对象不会保持迭代排序。

如果这不符合您的要求,您可以随时在django/contrib/admin中播放源代码。如果您需要维护迭代顺序,则可以使用UserDict或DictMixin替换AdminSite类中的_registry对象(在admin/sites.py中),该用户维护或DictMixin维护键的插入顺序。 (但是请大家多多关注一下,因为我自己从来没有做过这样的改变,我只是对Django如何迭代ModelAdmin对象的集合做出了有根据的猜测,我认为django/contrib /admin/sites.py是查找此代码的地方,而AdminSite类和register()和index()方法尤其是你想要的。)

很显然,这里最好的事情是您可以在自己的/admin.py模块中指定一个简单的选项。我相信那是你希望得到的答案。不过,我不确定这些选项是否存在。

+0

是的,我希望能够得到这样的答案并担心这种情况。我认为你是对的,至少从我能在文档中找到的东西。 我想我会保持原样。我不想维护我自己的django版本。 – 2008-12-29 18:27:52

0

我的解决方案是制作django.contrib.admin.sites.AdminSite和django.contrib.admin.options.ModelAdmin的子类。

我做到了这一点,因此我可以为每个应用程序显示更具描述性的标题,并订购每个应用程序中模型的外观。因此,我的settings.py中有一个字典,它将app_label映射为描述性名称以及它们应该出现的顺序,模型由我在每个ModelAdmin提供的序号字段排序,当我将它们注册到管理站点时。

尽管在文档中鼓励您自己的AdminSite和ModelAdmin的子类,但我的解决方案最终看起来像一个丑陋的黑客。

26

一种解决方法,你可以尝试是调整您的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的主干测试)。

祝你好运!

PS:对不起,如果这个答案发布得太晚,但它可以帮助其他类似的情况。

+0

这就是我正在使用的。尽管是一种解决方法,但它是最简单的方法。 – ePi272314 2016-06-20 18:06:10

+3

伤心。如果你有3个匹萨条目,最后会说“3 1. Pizzas”。 – user3526 2016-12-22 11:22:34

12

如果你想在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 

当然它不是ellegant,但可能工作了一段时间,才得到较好的解决。

+0

在最新的Django 1.11中工作。请注意,开头的空格不会被浏览器渲染,因此它对标题没有视觉影响。另请注意,这可与AppConfig类一起使用,以重新排序应用程序部分。 – Mrdev 2017-07-26 03:14:38

3

也可以使用缩小的代码,称为'Django Admin Index Custom App & Model Ordering' may be used。该片段只需3次简单的编辑即可解决问题。

这里有一个细节。 http://djangosnippets.org/snippets/2613/

17

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

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

app1不得与项目名称为前缀,即使用app1代替mysite.app1

+4

这将是伟大的,如果它实际上工作.. – thnee 2013-04-13 21:45:11

2

如果您使用Suit作为AdminSite,则可以使用menu tag进行菜单自定义。

5

这里的灵光使用的片段,更新的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 "" 

在设置。潘岳:

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 %} 
<h1 id="site-name">{% trans 'Django administration' %}</h1> 
{% endblock %} 

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

我正在寻找一个简单的解决方案,我可以在管理面板中按他们的名字订购应用程序。我想出了下面的模板标签:

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

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

然后,只需覆盖templates/admin/index.html并添加模板标签:

APP_ORDER = [ 
    'app1', 
    'app2', 
    # and so on... 
] 

{% 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 %} 

然后在settings.py定制APP_ORDER它在Django很好用1.10