自定义 Django 管理索引页面以显示模型对象

发布于 2024-12-05 19:21:58 字数 151 浏览 2 评论 0原文

在 Django 管理索引页面中,通常会列出应用程序及其模型。模型对象如何也列在该索引页中?我不仅想显示应用程序,还想显示其模型对象。应该如何定制呢?

在此处输入图像描述

In the Django admin index page, the app and its models will normally be listed. How can the model objects also be listed in this index page? Instead of displaying just the app, I want to also display its model objects. How should it be customized?

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橘虞初梦 2024-12-12 19:21:58

我希望我的网站具有相同的功能,并通过对核心 django 系统进行轻微修改来添加它。

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

class Meta:
    list_instances = True

第 2 步:
我们需要修改 Django 来识别和读取这个新属性。在 core-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

<强>第3步:
我们需要将此信息传递给生成索引页的模板。在 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,
}

第 4 步
最后一步是修改模板以支持这一点。编辑 core-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> </td>
        {% endif %}
    </tr>
    {% endfor %}
{% endif %}

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

第 5 步
你瞧!它应该看起来像这样:

在此处输入图像描述

编辑:
可选步骤 6
如果您希望实例名称也可单击,只需更改模板(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>

I wanted the same functionality for my site and added it by doing slight modifications to the core django system.

Step 1:
First we need a way to indicate which models should have their properties listed. Add the following code to the models for which you want the instances listed (in models.py):

class Meta:
    list_instances = True

Step 2:
We need to modify Django to recognize and read this new attribute. In core-django file: db/models/options.py, roughly at line 22 append 'list_instances' to 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')

and in the same file, roughly at line 52, create a default field for this attribute right after the other attributes :

self.list_instances = False

Step 3:
We need to pass this information along to the template that generates the index page. In core-django file: contrib/admin/sites.py, inside index() method and inside the "if has_module_perms:" part, add the following code:

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

This will create the list of instances to show, but only if the list_instance attribute is set. In the same file, a few lines further down, append these values to the "model_dict" construct.

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,
}

Step 4:
The final step is to modify the template to support this. Either edit the core-django file /contrib/admin/templates/admin/index.html or copy this file to the templates/admin/ directory of your specific app. Add a few lines after the standard code for generating rows to generate the "sub-rows" if applicable. Roughly at line 40, right between "/tr>" and "{% 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> </td>
        {% endif %}
    </tr>
    {% endfor %}
{% endif %}

This will cause the item to be listed with the name generated by the unicode() method in the model.

Step 5:
Lo and behold! It should look something like this:

enter image description here

Edit:
Optional Step 6:
If you want the instance names to be clickable too, just change the template (index.html) and replace:

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

with:

<td colspan="2" style="padding-left: 2em;">        
    {% if model.perms.change %}            
        <a href="{{ model.admin_url }}{{ instance.id}}">{{ instance }}</a>
    {% else %}
        {{ instance }}
    {% endif %}
</td>
从﹋此江山别 2024-12-12 19:21:58

更新 django 10 的 Setomidor 答案

总是很高兴回到这个干净的解决方案!

第 2 步 - 大约第 125 行(第 52 行)

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

_build_app_dict

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

添加步骤3 如第 430 行和第 460 行左右所述

instances = []


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

UPDATE Setomidor answer for django 10

Always great to come back to this clean solution!

step 2 - it is around line 125 (was 52)

step 3 - in sites.py - update the new method -

_build_app_dict

inside the for loop : for model, model_admin in models.items():

add step 3 as said around lines 430 and 460

instances = []


if (model._meta.list_instances == True):
    instances = model_admin.get_queryset(None)
月亮是我掰弯的 2024-12-12 19:21:58

您可以通过更改各种管理模板来完成此操作 - 根模板称为 app_index.html 并控制在那里显示的内容。调查发生情况的最佳方法是安装 django-debug-toolbar,然后查看每个视图使用的模板以找出如何自定义。

You can do this by changing the various admin templates - the root one is called app_index.html and controls what gets displayed there. The best way to investigate what's happening where is to install django-debug-toolbar and then look at the templates being used for each view to figure out how to customise.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文