Django 模板: 包含和扩展

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

所以我试着这么做:

返回文章页面

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

返回文章页面

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

问题是我似乎不能同时使用扩展和包含。有什么办法吗?如果没有,我怎样才能完成上述任务?

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

The purpose of this is to provide the same page in both pdf and html format, where the formatting is slightly different. The above question though simplifies what I'm trying to do so if I can get an answer to that it will solve my problem.

195937 次浏览

When you use the extends template tag, you're saying that the current template extends another -- that it is a child template, dependent on a parent template. Django will look at your child template and use its content to populate the parent.

您希望在子模板中使用的所有内容都应该在块中,Django 使用块来填充父模板。如果希望在该子模板中使用 include 语句,则必须将其放在块中,以便 Django 能够理解它。否则就没意义了姜戈也不知道该怎么办。

Django 文档提供了一些非常好的示例,说明如何使用块替换父模板中的块。

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

More info about why it wasn't working for me in case it helps future people:

之所以无法正常工作,是因为 django 中的{% include% }不喜欢特殊字符,比如花哨的撇号。我试图包含的模板数据是从 word 粘贴的。我必须手动删除所有这些特殊字符,然后它包括成功。

来自姜戈文档:

Include 标签应该被看作是“呈现这个子模板并包含 HTML”的实现,而不是“解析这个子模板并包含它的内容,就好像它是父模板的一部分”。这意味着包含的模板之间不存在共享状态——每个包含都是一个完全独立的呈现过程。

所以 Django 不会从 commdata.html 中获取任何块,它也不知道如何处理外部块呈现的 html。

增加了参考未来的人谁发现这通过谷歌: 你可能想要看看在这样的情况下,夹层库提供的{% 过度扩展% }标记。

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

来自 文件:

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

不要将“ page1.html”和“ page2.html”分开,而是将 {% extends base_template %}放在“ commdata.html”的顶部。然后在您的视图中,将 base_template定义为“ base1.html”或“ base2.html”。

编辑2015年12月10日 : 正如评论中指出的那样,Ssi从1.8版本开始就已经被弃用了。根据文档:

此标记已被弃用,将在 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

Beware also of the security implications of this technique and also of the required ALLOWED_INCLUDE_ROOTS define, which must be added to your settings files.

这应该可以解决您的问题: 将 include 标记放在块部分中。

返回文章页面

{% extends "base1.html" %}


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

返回文章页面

{% extends "base2.html" %}


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