2009-09-11 106 views
73

我想在2个不同的基本文件中提供相同的内容。django模板:包含并扩展

所以我想这样做:

page1.html:

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

page2.html:

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

的问题是,我似乎无法使用都延伸和包括。有没有办法做到这一点?如果不是,我怎么能完成上述?

commondata.html将覆盖在两个base1.html和base2.html

这样做的目的是在两个PDF和HTML格式,其中的格式是稍有不同提供相同的页中指定的块。上面的问题虽然简化了我想要做的事情,但如果我能得到答案,它将解决我的问题。

回答

83

当您使用扩展模板标记时,您说当前模板扩展了另一个 - 它是一个子模板,依赖于父模板。 Django会查看您的子模板并使用其内容来填充父级。

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

Django文档有几个非常好的使用块代替父模板中块的示例。为什么它没有的情况下,工作对我来说

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

+1

我commondata.html中有定义的块。但它并没有取代父tempalte的块...如果不是做一个include,我会在page1.html和page2.html中两次写入确切的数据,当然它的确行得通。但是我想把这个共同点分解为commondata.html。 – 2009-09-11 04:17:16

+0

我会尝试在一个块内,但我想我以前尝试过... – 2009-09-11 04:18:12

+0

似乎工作,我记得尝试这一点,但我一定有一个错字或什么的时候导致它不工作。 – 2009-09-11 04:19:35

9

更多信息它有助于未来的人:

为什么它不工作的原因是,{%包含%}在Django没有按”不喜欢像花哨的撇号这样的特殊字符。我试图包含的模板数据是从单词中粘贴的。我不得不手动删除所有这些特殊字符,然后成功包含它。

64

从Django文档:

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

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

2

添加引用未来通过谷歌搜索到的人:您可能希望查看夹层库为此类情况提供的{%overextend%}标记。

3

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

documentation

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

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

1

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

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


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

然而,我有点吃惊,没有人提到由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/en/1.8/ref/templates/builtins/#std:templatetag-include](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/# STD:templatetag-包括) – 2015-12-09 23:55:46

5

这应该为你做窍门:把include标签放在块区域内。

page1.html:

{% extends "base1.html" %} 

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

page2.html:

{% extends "base2.html" %} 

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