Django模板中的“{% extends %}”和“{% include %}”

ruyhziif  于 2023-05-19  发布在  Go
关注(0)|答案(8)|浏览(155)

我想提供相同的内容内2个不同的基础文件。
所以我试着这样做:
page1.html:

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

page2.html:

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

问题是我似乎不能同时使用extends和include。有什么办法可以做到吗?如果没有,我该如何实现上述目标?
commondata.html覆盖在base1.htmlbase2.html中指定的块
这样做的目的是以pdfhtml提供相同的页面,其中格式略有不同。上面的问题虽然简化了我想做的事情,如果我能得到答案,它将解决我的问题。

dxpyg8gm

dxpyg8gm1#

当使用extends template标记时,就是说当前模板扩展了另一个模板--它是一个依赖于父模板的子模板。Django将查看您的子模板并使用其内容填充父模板。
你想在子模板中使用的所有东西都应该在块中,Django使用这些块来填充父模板。如果你想在子模板中使用include语句,你必须把它放在一个块中,Django才能理解它。否则它就是没有意义,Django不知道该怎么处理它。
Django文档中有一些非常好的例子,使用块来替换父模板中的块。
https://docs.djangoproject.com/en/dev/ref/templates/language/#template-inheritance

rjee0c15

rjee0c152#

Django文档:
include标签应该被认为是“渲染这个子模板并包含HTML”的实现,而不是“解析这个子模板并包含它的内容,就好像它是父模板的一部分一样”。这意味着在包含的模板之间没有共享状态--每个包含都是一个完全独立的呈现过程。
所以Django不会从commondata.html中抓取任何块,也不知道如何处理块外的渲染html。

jpfvwuh4

jpfvwuh43#

这应该对你有帮助:把include标签放在一个块段中。
page1.html:

{% extends "base1.html" %}

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

page2.html:

{% extends "base2.html" %}

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

7cwmlq894#

更多关于为什么它不为我工作的信息,以防它帮助未来的人:
它不起作用的原因是Django中的{% include %}不喜欢特殊字符,比如花哨的撇号。我试图包含的模板数据是从word粘贴的。我不得不手动删除所有这些特殊字符,然后它包括成功。

cx6n0qe3

cx6n0qe35#

不能将块从包含的文件拉入子模板以覆盖父模板的块。但是,您可以在变量中指定父级,并在上下文中指定基模板。
来自文档:
{% extends variable %}使用变量的值。如果变量的计算结果是一个字符串,Django将使用该字符串作为父模板的名称。如果变量的计算结果是Template对象,Django将使用该对象作为父模板。
不要将“page1.html”和“page2.html”分开,而是将{% extends base_template %}放在“commondata.html”的顶部。然后在视图中,将base_template定义为“base1.html”或“base2.html”。

bwitn5fc

bwitn5fc6#

添加以供将来通过谷歌找到此内容的人参考:对于这种情况,您可能需要查看夹层库提供的{% overextend %}标记。

ryhaxcpt

ryhaxcpt7#

编辑2015年12月10日:正如注解中所指出的,ssi 从1.8版开始就被弃用了。根据文件:

此标签已被弃用,并将在Django 1.10中删除。改为使用include标记。
在我看来,这个问题的正确(最好)答案是来自podshumok的答案,因为它解释了为什么在继承沿着使用include的行为。
然而,我有点惊讶的是,没有人提到Django模板系统提供的ssi标签,它是专门为 inline 设计的,包括一段外部的 text。这里,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定义,它必须添加到您的设置文件中。

hgqdbh6s

hgqdbh6s8#

您可以在一个模板中同时使用{% extends %}和{% include %}。
例如,下面有base.html,它显示Base

# "templates/base.html"

<p>Base</p>

{% block content %}{% endblock %}

下面是additional.html,显示Additional

# "templates/additional.html"

<p>Additional</p>

下面是index.html,显示Index

# "templates/index.html"

<p>Index</p>

现在,您可以扩展base.html并将additional.html包含在{% block %}中,除了index.html中的<p>Index</p>,如下所示,然后使用Django View渲染index.html

# "templates/index.html"

{% extends "base.html" %}

{% block content %}
    <p>Index</p>
    {% include "additional.html" %}
{% endblock %}

然后显示BaseIndexAdditional,如下所示:

Base

Index

Additional

请注意,下面{% block %}之外的代码和下面base.html没有的{% block %}内部的代码在index.html中被忽略:

# "templates/index.html"

{% extends "base.html" %}

<p>Index</p>
{% include "additional.html" %}

{% block test %}
    <p>Index</p>
    {% include "additional.html" %}
{% endblock %}

因此,仅显示Base,如下所示:

Base

相关问题