2008-12-29 126 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