2010-10-19 54 views
42

如果要覆盖使用一个应用程序来在Django(在app /模板/应用/)在另一个目录中创建一个同名的模板模板,该模板加载器检查在应用程序的模板目录之前。如果你只是想覆盖模板的某些块,你还必须复制整个模板并改变该块,这实际上不是非常干燥。Django的:重写和扩展的应用程序模板

是否有人知道的方式来覆盖orginial模板,而在同一时刻扩展它,这样你只需要重写你想改变的特定块? (事情是这样更改模板的名称,因为在某些情况下,你可能需要更改视图,使其与其他模板工作)

编辑:正如亚当·泰勒在评论中指出,从Django 1.9 on了这一点是可能的,没有任何黑客。

+0

@paulo:据我所知,大约有一般重写应用程序的模板,当然文档的,因为这是日常工作,但我从来没有见过任何东西关于扩展具有相同名称的模板。如果您知道这是在文档中,请将我指向该地点... – 2010-10-19 11:38:29

+0

http://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-vs-replacing-an-admin-template – 2010-10-19 11:53:30

+1

此处的方法仅适用于特定于应用程序的管理模板,因为这些模板将转到与原始模板不同的路径。Iguess这就是为什么这是在*管理*文档,而不是在一般;) – 2011-09-14 16:19:43

回答

34

我觉得从this related question答案是相关的;目前,最好的解决方案似乎是使用来自django-apptemplates package on PyPI的自定义模板加载器,因此您只需使用pip即可安装它(例如pip install django-apptemplates)。

模板加载器允许您在特定的应用程序中扩展模板;例如,延长管理inteface的索引页,你会增加

'apptemplates.Loader', 

TEMPLATE_LOADERS列表settings.py,并使用

{% extends "admin:admin/index.html" %} 
在模板

+1

我正在使用这个片段来解决这个确切的问题。我感到惊讶的是,更多人没有触及它:一个想调整现有页面部分的应用程序。 – 2012-02-02 00:59:20

+2

我认为这是一个常见问题,但人们通过复制完整模板来制作。如果有人尝试过,覆盖和延伸通常以无限递归结束。这个问题在这张票上描述:https://code.djangoproject.com/ticket/15053 – Nagyman 2012-03-24 22:01:12

-1

[更新]

我误解了问题,我原来的答复仅适用于管理应用程序,它有一个内置的模板扩展机制。对于缺乏这种机制的其他应用程序,我只需分叉原始模板,而不是像自定义的模板加载器那样摆弄选定的答案。如果你担心分叉,你也可以实施一个扩展机制,如果你认为它是值得的,那么回馈到原始项目。


[原创答案]

直从细manual: 由于管理模板的模块化设计,它通常是既无必要,也建议更换整个模板。只覆盖模板中需要更改的部分几乎总是更好。

继续上面的例子中,我们要添加旁边的历史工具的页面模型一个新的链接。在查看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目录中,我们的链接将出现在每个模型的更改表单上。

+0

感谢张贴这个,但我的问题不是关于管理模板。我正在寻找这样的(前端)模板,例如。与第三方应用程序,我可能只是想改变一个块,并复制整个休息,以覆盖只是一个部分看起来像一些干违反我... – 2010-10-19 12:10:37

+1

@lazerscience:这是相同的过程,除了在你的模板目录,你应该遵守与你重写的模板相同的目录结构。检查:http://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.loader.select_template – 2010-10-19 14:15:20

+4

我不认为这仍然回答原来的问题。假设'niceapp.views.index()'使用模板'niceapp/index.html'。如果我想使用原始视图但自定义模板,我可以在我的项目或我自己的应用程序的'templates'目录中创建一个'niceapp/index.html'。但是,如何扩展原始并覆盖一些块,而不是复制整个模板?说'{%extend'niceapp/index.html“%}'显然不能完成这项工作。 – akaihola 2010-10-27 08:11:05

2

在Django的维基,西蒙·威利森呈现a trick实现了“扩大自模板”的效果。但是,如果您使用app_directories模板加载器,则它不是直接适用的。

符号链接的应用程序的新目录中的模板目录可能做一招。

+0

谢谢,这也不是我正在寻找的100%,但我不认为你能接近;在为不同的网站定制模板时已经做了类似的事情! – 2010-10-27 11:13:31

-3

一个简单的方法来做到这一点是这样的:

比方说,你想扩展和覆盖Django的/的contrib /管理/模板/管理/ change_form.html。

首先,将原始change_form.html复制到您的应用程序的模板目录,并将其重命名为类似myapp/templates/admin/original_change_form.html的内容。 (您也可以将其作为符号链接来执行此操作。)

其次,在myapp/templates/admin中创建您自己的change_form.html。在它的顶部,把以下内容:

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

简单!

+0

这实际上不是一个坏的解决方案,特别是如果你的系统支持符号链接。 – Flimm 2016-08-11 10:52:48

6

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

而且很容易与PIP安装:

pip install -U django-overextends 
+0

哇,这是超级简单和轻量级!爱它!谢谢! – 2014-10-30 18:08:58

+0

仅供参考Django 1.4的最新版本是0.3.2,后者需要1.7 – 2015-09-30 14:46:48

3

的Django 1.9及更高版本具有this feature

Django的模板加载器现在可以递归扩展模板。

所以你可以有从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> 
+0

我已经尝试过这种设置,它似乎无法工作。 – HoHo 2016-09-29 15:25:08

+0

@HoHo你正在使用哪个Django版本? – Flimm 2016-10-03 08:43:36

+0

我使用的是1.10 - 如果'app1'有一组相互关联的模板(比如'app1/templates/app1/base.html',它由'app1/templates/app1/subfolder/subsite.html'扩展) ,模板'app2'应该如何扩展这两个模板?我想通过你的方法 - 在'app1'中复制文件夹层次结构和文件名的方法 - 可以工作,但看起来似乎不行。 – HoHo 2016-10-03 18:42:57