django模板:包含和扩展

时间:2009-09-11 04:08:39

标签: python django django-templates

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

所以我试图这样做:

page1.html:

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

page2.html:

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

问题是我似乎无法同时使用extends和include。有办法做到这一点吗?如果没有,我怎样才能完成上述工作?

commondata.html会覆盖base1.html和base2.html

中指定的块

这样做的目的是以pdf和html格式提供相同的页面,其格式略有不同。上面的问题虽然简化了我正在尝试的内容,但如果我能得到答案,它将解决我的问题。

7 个答案:

答案 0 :(得分:97)

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

您想要在子模板中使用的所有内容都应该在块中,Django用它来填充父级。如果你想在那个子模板中使用include语句,你必须把它放在一个块中,让Django理解它。否则它只是没有意义,Django不知道如何处理它。

Django文档中有一些非常好的例子,可以使用块来替换父模板中的块。

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

答案 1 :(得分:71)

来自Django docs:

  

include标记应该被视为“渲染此子模板并包含HTML”的实现,而不是“解析此子模板并将其内容包含在内,就好像它是父节点的一部分”。这意味着包含的模板之间没有共享状态 - 每个包含都是完全独立的渲染过程。

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

答案 2 :(得分:14)

这应该可以解决这个问题:在块部分中放入include标签。

page1.html:

B

page2.html:

{% extends "base1.html" %}

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

答案 3 :(得分:12)

有关为什么它不适合我的更多信息,以防万一它可以帮助未来的人:

它不起作用的原因是django中的{%include%}不喜欢花式撇号这样的特殊字符。我试图包含的模板数据是从word中粘贴的。我不得不手动删除所有这些特殊字符,然后成功包含它。

答案 4 :(得分:3)

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

来自documentation

  

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

而不是单独的“page1.html”和“page2.html”,将{% extends base_template %}放在“commondata.html”的顶部。然后在您看来,将base_template定义为“base1.html”或“base2.html”。

答案 5 :(得分:2)

已添加以供将来通过Google查找此内容的人参考:您可能需要查看夹层库提供的{%overextend%}标记,以了解此类情况。

答案 6 :(得分:1)

2015年12月10日编辑:正如评论中所指出的,自版本1.8以来, ssi 已弃用。根据文件:

  

此标记已弃用,将在Django 1.10中删除。请改用include标记。


在我看来,这个问题的正确(最佳)答案来自 podshumok ,因为它解释了为什么包含在继承中使用时的行为。

然而,我有点惊讶没有人提到Django模板系统提供的 ssi 标签,该标签是专为内联设计的,包括的外部部件文本。在这里, inline 意味着外部文本不会被解释,解析或插入,而只是“复制”在调用模板中。

请参阅文档以获取更多详细信息(请务必在页面右下方的选择器中查看相应版本的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定义,必须将其添加到您的设置文件中。