Django:当管理模板已经被覆盖时无法进行覆盖?

4
为了向Django模型的管理界面添加一些内容,我想覆盖change_form.html模板。根据文档,我需要在路径 /project-path/templates/admin/appname/modelname/中创建一个名为change_form.html的文件。当然,我需要确保这个路径也在TEMPLATE_DIRS中可用。这样的文件可能如下所示:
{% extends "admin/change_form.html" %}
{% load i18n  %}

{% block after_field_sets %}
SOME CONTENT
{% endblock %}

然而,我利用 django-guardian 进行对象权限管理。这个 Django 应用程序也覆盖了 change_form.html (运行正常--相关源代码看起来像是 这里),但 Django 没有捕捉到我的模板扩展文件(例如上面示例中的 "SOME CONTENT" 未显示)。我想要覆盖的块/部分与 django-guardian 覆盖的不同,并且最终我想要将 django-guardion 的 change_form.html 添加到我的模板中。

那么我做错了什么?多个应用程序覆盖管理模板可行吗?

如果感兴趣,这是我的 TEMPLATE_LOADERS 设置:

TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader'
)

此外,django-guardian是INSTALLED_APPS数组中的最后一个应用程序。

2个回答

5

一个可能的解决方案是通过引用和覆盖django-guardian模板(在这里定义)来显式定义继承链,而不是使用Django的通用change_form.html。因此,不要使用:

{% extends "admin/change_form.html" %}

在我的自定义模板的开头,我需要使用:
{% extends "admin/guardian/model/change_form.html" %}

此外,我需要扩展我的GuardedModelAdmin子类模型,明确使用自己的模板文件作为更改表单模板:
class MyModel(GuardedModelAdmin):
    change_form_template = 'admin/appname/mymodel/change_form.html'

这样做可以达到效果,但是它会在模板和模型中添加一个明确的依赖关系。当然,模型本来就有这个依赖关系了,但我很想知道是否还有一种只涉及默认的change_form.html的解决方案--然而,我怀疑这并不真正可行。


3

如果你的模板路径在TEMPLATE_DIRS中,那么你可以反转TEMPLATE_LOADERS的顺序。

如果你的模板在你的应用程序中,则需要在INSTALLED_APPS数组中将你的应用程序添加在django-guardian之后。

基本上,如果存在名称冲突,则将使用最后加载的模板。


问题不在于覆盖模板,而是在使用第三方应用程序时进行两次覆盖。 - maazza
Django不会自动合并模板,基本上你不能两次覆盖模板,但你可以在你的模板中添加 {% include "admin/guardian/model/change_form.html" %},并只使用你的模板。 - Meehow
关于您提到的第二点,文档和我的经验表明,在INSTALLED_APPS中,Django找到的第一个模板将被使用。因此,如果您正在尝试从应用程序覆盖admin/base_site.html,则您的应用程序最好排在第一位。请参见https://docs.djangoproject.com/en/1.7/ref/templates/api/#django.template.loaders.app_directories.Loader - mlncn
@mlncn 我在2013年编写了它,它适用于Django 1.5。我不知道当前的状态如何。 - Meehow
在Django 1.11中又有了变化。现在你需要使用设置FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'https://docs.djangoproject.com/en/1.11/ref/forms/renderers/ - Meehow

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