Django:覆盖和扩展应用程序模板

如果您想在django(在app / templates / app /)中覆盖随应用程序提供的模板,则可以在另一个目录中创build一个同名的模板,模板加载器在应用程序的模板目录之前检查该模板。 如果你只是想覆盖模板的某些块,你也必须复制整个模板广告改变该块,这实际上不是非常干燥。

有没有人知道一种方法来覆盖原始模板,同时扩展它,所以你只需要重写你想改变的特定块? (事情是这样做的, 而不更改模板的名称,因为在某些情况下,您可能必须更改视图,使其与另一个模板)

编辑:正如Adam Taylor在Django 1.9的评论中指出的那样,没有任何黑客可能。

我认为这个相关问题的答案是中肯的。 目前,最好的解决scheme似乎是使用PyPI上的django-apptemplates软件包中的自定义模板加载器,因此您可以使用pip来安装它(例如pip install django-apptemplates )。

模板加载器允许您在特定的应用程序中扩展模板; 例如,要扩展pipe理界面的索引页面,您可以添加

 'apptemplates.Loader', 

settings.pyTEMPLATE_LOADERS列表,然后使用

 {% extends "admin:admin/index.html" %} 

在您的模板。

作为一个更新,因为这似乎是一个受欢迎的问题。 我已经使用了过度的应用程序没有任何问题。 它提供了一个新的关键字过度扩展,允许扩展具有相同名称的模板。

而且用pip很容易安装:

  pip install -U django-overextends 

Django 1.9和更高版本有这个function :

Django模板加载器现在可以recursion地扩展模板。

所以你可以从app1获得一个文件,内容如下:

app1/templates/example/foobar.html

 <p>I'm from app1</p> {% block main %}{% endblock %} 

你可以用app2的文件扩展它(注意模板名称example/foobar.html是相同的):

app2/templates/example/foobar.html

 {% extends "example/foobar.html" %} {% block main %} <p>I'm from app2</p> {% endblock %} 

最终结果应该是:

 <p>I'm from app1</p> <p>I'm from app2</p> 

在Django wiki中,Simon Willison提出了实现“自我扩展模板”效果的技巧 。 但是,如果您使用的是app_directories模板加载器,则不是直接适用的。

在一个新目录中添加应用程序的模板目录可能会有一些窍门。

[更新]

我误解了这个问题,我原来的答案只适用于pipe理应用程序,它有一个内置的模板扩展机制。 对于缺乏这种机制的其他应用程序,我只是叉原始模板,而不是像自定义的模板加载器摆弄select的答案build议。 如果你担心分叉,你也可以实现一个扩展机制,如果你觉得这个扩展机制是值得的,可以回到原来的项目上。


[原始回答]

直接从精细的手册 :由于pipe理模板的模块化devise,通常既不必要也不可取代整个模板。 只覆盖模板中需要更改的部分几乎总是更好。

为了继续上面的例子,我们要为Page模型的历史logging工具旁边添加一个新的链接。 在查看change_form.html之后,我们确定我们只需要重写object-tools块。 因此,这里是我们新的change_form.html:

 {% extends "admin/change_form.html" %} {% load i18n %} {% block object-tools %} {% if change %}{% if not is_popup %} <ul class="object-tools"> <li><a href="history/" class="historylink">{% trans "History" %}</a></li> <li><a href="mylink/" class="historylink">My Link</a></li> {% if has_absolute_url %} <li><a href="../../../r/{{ content_type_id }}/{{ object_id }}/" class="viewsitelink"> {% trans "View on site" %}</a> </li> {% endif%} </ul> {% endif %}{% endif %} {% endblock %} 

而就是这样! 如果我们把这个文件放在templates / admin / my_app目录下,我们的链接就会出现在每个模型的变化表单上。

一个简单的方法是这样的:

假设您想扩展并覆盖django / contrib / admin / templates / admin / change_form.html。

首先,将原始的change_form.html文件复制到应用程序的模板目录中,并将其重命名为myapp / templates / admin / original_change_form.html。 (你也可以把它作为符号链接。)

其次,在myapp / templates / admin中创build自己的change_form.html。 在顶部,放置以下内容:

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

简单!