定制Django管理页面的索引页以显示模型对象

11
在Django管理界面的索引页面中,通常会列出应用程序及其模型。如何在此索引页面上列出模型对象?我想要显示应用程序及其模型对象,而不仅仅是显示应用程序。应该如何自定义?

enter image description here

3个回答

16

我希望在我的网站上实现相同的功能,并通过对Django核心系统进行轻微修改来添加它。

步骤1: 首先,我们需要一种方法来指示哪些模型应列出其属性。将以下代码添加到要列出实例的模型(在models.py中)中:

class Meta:
    list_instances = True

步骤2:我们需要修改Django以识别并读取这个新属性。在核心的Django文件db/models/options.py中,大致在第22行将'list_instances'追加到DEFAULT_NAMES列表中:

DEFAULT_NAMES = ('verbose_name', 'verbose_name_plural', 'db_table', 'ordering',
             'unique_together', 'permissions', 'get_latest_by',
             'order_with_respect_to', 'app_label', 'db_tablespace',
             'abstract', 'managed', 'proxy', 'auto_created', 'list_instances')

并且在同一个文件中,大约在第52行,在其他属性之后为该属性创建一个默认字段:

self.list_instances = False

第三步: 我们需要将这些信息传递给生成索引页面的模板。在core-django文件contrib/admin/sites.py中,在index()方法和"if has_module_perms:"部分内部添加以下代码:

instances = []
if (model._meta.list_instances == True):
    instances = model_admin.queryset(None)

如果设置了list_instance属性,这将创建要显示的实例列表。在同一文件中,在几行代码之后,将这些值附加到“model_dict”构造中。

model_dict = {
    'name': capfirst(model._meta.verbose_name_plural),
    'admin_url': mark_safe('%s/%s/' % (app_label, model.    __name__.lower())),
    'perms': perms,
    'list_instances':model._meta.list_instances,
    'instances': instances,
}

第四步: 最后一步是修改模板以支持此功能。要么编辑核心Django文件/contrib/admin/templates/admin/index.html,要么将此文件复制到特定应用程序的templates/admin/目录中。在生成行的标准代码之后添加几行代码来生成“子行”(如果适用)。大约在第40行,在“/tr>”和“{% endfor %}”之间:

{% if model.list_instances %}
    {% for instance in model.instances %}
    <tr>
        <td colspan="2" style="padding-left: 2em;">{{ instance }}</td>
        {% if model.perms.change %}
            <td><a href="{{ model.admin_url }}{{ instance.id }}/" class="changelink">{% trans 'Change' %}</a></td>
        {% else %}
            <td>&nbsp;</td>
        {% endif %}
    </tr>
    {% endfor %}
{% endif %}

这将导致该项在模型中以由 unicode() 方法生成的名称列出。

第五步: 哇!它应该看起来像这样:

输入图像描述

编辑: 可选的第六步: 如果您也希望实例名称可点击,请更改模板(index.html)并替换为:

<td colspan="2" style="padding-left: 2em;">{{ instance }}</td>

使用:

<td colspan="2" style="padding-left: 2em;">        
    {% if model.perms.change %}            
        <a href="{{ model.admin_url }}{{ instance.id}}">{{ instance }}</a>
    {% else %}
        {{ instance }}
    {% endif %}
</td>

2
没问题。 :) 我自己也需要它。如果你在点击特定应用程序时也想要它,请再次转到contrib/admin/sites.py,并像在index()方法中所做的那样,在app_index()方法中添加相同的几行。 - Setomidor
2
很棒的信息。是否可能不修改核心文件来完成步骤2和3中的操作--例如,是否有一种打补丁的方法? - billrichards
我不知道有没有。:/ - Setomidor

2

更新Setomidor对Django 10的答案

很高兴能回到这个简洁的解决方案!

第二步 - 大约在第125行(之前是52行)

第三步 - 在sites.py中更新新方法 -

_build_app_dict

在for循环内部:for model, model_admin in models.items():

根据第430和460行附近所说,添加第3步骤。

instances = []


if (model._meta.list_instances == True):
    instances = model_admin.get_queryset(None)

1
你可以通过更改各种管理模板来实现这一点 - 根模板称为app_index.html,控制着在那里显示的内容。最好的方法是安装django-debug-toolbar,然后查看每个视图使用的模板,以找出如何自定义的方法。

1
完全正确...但这是一条漫长而黑暗的道路,我以前尝试过。django-admin并不是特别模块化或可扩展的。你确定用户不能先点击其中一个链接吗? - Dave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接