【问题标题】:django templates: include and extendsdjango 模板:包含和扩展
【发布时间】:2010-11-27 09:25:25
【问题描述】:

我想在 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 格式的相同页面,其中格式略有不同。上述问题虽然简化了我正在尝试做的事情,但如果我能得到答案,它将解决我的问题。

【问题讨论】:

    标签: python django django-templates


    【解决方案1】:

    当你使用扩展模板标签时,你是说当前模板扩展了另一个模板——它是一个子模板,依赖于一个父模板。 Django 将查看您的子模板并使用其内容填充父模板。

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

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

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

    【讨论】:

    • 我的 commondata.html 中定义了块。但它并没有取代父模板的块......如果我不做一个包含而是在 page1.html 和 page2.html 中写入两次确切的数据,那么它当然可以工作。但我想将这种共性分解到 commondata.html 中。
    • 似乎有效,我记得试过这个,但我当时一定是有错字或其他什么导致它不起作用。
    • 请参阅下面的答案,了解为什么它第一次对我不起作用,但我会留给您接受的答案,因为您回答了我提出的问题。
    【解决方案2】:

    更多关于为什么它对我不起作用的信息,以防它对未来的人有所帮助:

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

    【讨论】:

      【解决方案3】:

      来自 Django 文档:

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          来自documentation

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

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

          【讨论】:

            【解决方案6】:

            2015 年 12 月 10 日编辑:正如 cmets 中所指出的,ssi 自 1.8 版起已弃用。根据文档:

            此标签已被弃用,将在 Django 1.10 中删除。请改用包含标签。


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

            然而,让我有些惊讶的是,没有人提到 Django 模板系统提供的 ssi 标签,它是专门为 inline 设计的,包括一个外部的 文本。这里,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 定义,必须将其添加到您的设置文件中。

            【讨论】:

            【解决方案7】:

            这应该可以为您解决问题:将包含标记放在块部分内。

            page1.html:

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

            page2.html:

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

            【讨论】:

            • 完美。为我工作。
            猜你喜欢
            • 2019-03-05
            • 2019-04-21
            • 1970-01-01
            • 2012-04-17
            • 1970-01-01
            • 2017-04-24
            • 2012-01-10
            • 2010-11-27
            相关资源
            最近更新 更多