django模板:包括和扩展


108

我想在2个不同的基本文件中提供相同的内容。

所以我正在尝试这样做:

page1.html:

{% extends "base1.html" %}
{% include "commondata.html" %}

page2.html:

{% extends "base2.html" %} 
{% include "commondata.html" %}

问题是我似乎无法同时使用扩展和包含。有什么办法吗?如果没有,我该如何完成以上工作?

commondata.html覆盖base1.html和base2.html中指定的块

这样做的目的是提供pdf和html格式的同一页面,但格式略有不同。上面的问题虽然简化了我要尝试做的事情,但是如果我可以得到答案,它将解决我的问题。

Answers:


110

使用扩展模板标签时,是指当前模板扩展了另一个模板-它是子模板,取决于父模板。Django将查看您的子模板,并使用其内容填充父模板。

您想要在子模板中使用的所有内容都应位于block之内,Django使用该块来填充父模板。如果要在该子模板中使用include语句,则必须将其放在一个块中,以便Django理解。否则,这只是没有意义,而Django不知道该怎么做。

Django文档中有一些非常好的示例,这些示例使用块替换父模板中的块。

https://docs.djangoproject.com/zh-CN/dev/ref/templates/language/#template-inheritance


1
我的commondata.html中定义了块。但这并不能代替父级临时模板的块...如果不进行包含,而是在page1.html和page2.html中两次写入确切的数据,那么它当然可以工作。但是我想在commondata.html中排除这种共同性。
网民

似乎可以正常工作,我记得尝试过这种方法,但是我当时一定有错别字或其他东西导致它无法工作。
网民

1
请参阅下面的答案,了解为什么它第一次对我不起作用,尽管您回答了我正确提出的问题,但我还是会给您一个可以接受的答案。
网民

80

从Django文档中:

include标记应被视为“呈现此子模板并包含HTML”的实现,而不应视为“解析此子模板并像其父对象一样包含其内容”。这意味着在包含的模板之间没有共享状态-每个包含都是一个完全独立的呈现过程。

因此,Django不会从您的commondata.html中获取任何块,并且它也不知道如何处理呈现的html外部块。


32

这应该为您解决了问题:将include标签放在块部分中。

page1.html:

{% extends "base1.html" %}

{% block foo %}
   {% include "commondata.html" %}
{% endblock %}

page2.html:

{% extends "base2.html" %}

{% block bar %}
   {% include "commondata.html" %}
{% endblock %}

1
完善。为我工作。
Trupti M Panchal

13

如果它对将来的人有帮助,为什么它对我不起作用的更多信息:

之所以不起作用,是因为django中的{%include%}不喜欢像特殊的撇号这样的特殊字符。我尝试包含的模板数据是从Word粘贴的。我必须手动删除所有这些特殊字符,然后成功包含其中。


3

您不能将包含文件中的块拉入子模板以覆盖父模板的块。但是,您可以在变量中指定父项,并在上下文中指定基本模板。

文档中

{%扩展变量%}使用变量的值。如果该变量的值为字符串,则Django将使用该字符串作为父模板的名称。如果该变量的值为模板对象,则Django将使用该对象作为父模板。

代替单独的“ page1.html”和“ page2.html”,放在“ commondata.html” {% extends base_template %}的顶部。然后在您的视图中,定义base_template为“ base1.html”或“ base2.html”。


2

添加以供将来通过Google找到它的人参考:对于此类情况,您可能需要查看夹层库提供的{%overextend%}标签。


1

编辑2015年12月10日:正如评论中指出的那样,自1.8版起不推荐使用ssi。根据文档:

该标签已被弃用,并将在Django 1.10中删除。请改用include标签。


在我看来,这个问题的正确答案(最好)是podshumok提出的答案,因为它解释了为什么在与继承一起使用时include的行为。

但是,令我感到有些惊讶的是,没有人提到Django模板系统提供的ssi标记,该标记是专门为内联式设计的,包括一个外部文本。在此,内联表示不会解释,解析或插入外部文本,而只是在调用模板内部“复制”。

请参考文档以获取更多详细信息(请确保在页面右下方的选择器中检查您所使用的Django版本)。

https://docs.djangoproject.com/en/dev/ref/templates/builtins/#ssi

从文档中:

ssi
Outputs the contents of a given file into the page.
Like a simple include tag, {% ssi %} includes the contents of another file
 which must be specified using an absolute path  in the current page

还请注意此技术的安全隐患以及必需的ALLOWED_INCLUDE_ROOTS定义,必须将其添加到设置文件中。


1
请注意,从1.8版本开始,不推荐使用ssi,而推荐使用Include。https://docs.djangoproject.com/zh-CN/1.8/ref/templates/builtins/#std:templatetag-include
Tim S.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.