【问题标题】:Why does it look like template inheritance only works with nested blocks?为什么看起来模板继承只适用于嵌套块?
【发布时间】:2020-03-03 04:16:57
【问题描述】:

您好,我有以下 3 个模板(为了本文的目的而进行了简化):

1 - base.html:

//link stylesheet

{% block page_content %}
{% endblock %}

//add bootstrap, jQuery and run scripts

2 - base_app.html:

{% extends "base.html" %}

{% block page_content %}
//html here
{% endblock page_content %}

{% block page_app %}
{% endblock page_app %}

3 - base_app_main.html:

{% extends "base_app.html"%}

{% block page_app %}

//html i wanna display when I call render(request, 'base_app_main.html', context)

{% endblock page_app %}

就像现在一样,当我显示3 - base_app_main.html 时,它不会显示{% block page_app %}block 内的部分,但是如果我将2 - base_app.html 更改为如下所示,它就会起作用:

2 - 修改 base_app.html:

{% extends "base.html" %}

{% block page_content %}
//html here
{% block page_app %}
{% endblock page_app %}
{% endblock page_content %}

我不明白为什么模板继承在第一种情况下不起作用而在第二种情况下起作用?

我能找到的文档或在线教程没有给出相关的多重继承示例。

【问题讨论】:

    标签: django python-3.x django-templates


    【解决方案1】:

    我认为它在docs 关于模板继承的描述非常清楚

    如果你在模板中使用 {% extends %} ,它必须是第一个模板 该模板中的标记。否则模板继承将不起作用。

    您所做的第一次尝试基本上是 {% extend %} 在 1 个模板中的 {% extend %} 内,它导致主模板是您的 base.html 有 2 个扩展标签。这等于Template inheritance won’t work

    【讨论】:

    • 但是 {% extends % } 在这两种情况下都是我所有 3 个模板中的第一个模板标签...
    • 当你渲染你的 base_app_main 时,你也会同时渲染你的 base_app 和 base,所以它被认为是 1 页带有 2 个扩展标签或另一个词是 1 个模板
    【解决方案2】:

    因此,对于任何陷入同一点的人来说,在线教程中的这个解释让我明白了:

    在第 1 行,{% extends "base.html" %} 告诉 Django 模板引擎当前模板是子模板,并且继承自 base.html。这必须是子模板中的第一行,否则它将不起作用。当模板引擎遇到此行时,它会立即加载父模板(即 base.html),然后将父模板中的内容块替换为子模板中定义的同名内容块。

    基本上,在这些继承方案中实际呈现的模板是祖先或此处base.html。如果您仔细阅读以下内容:

    然后将父模板中的内容块替换为 子模板中定义的同名内容块

    您会看到,在第一种情况下,当我渲染base.html时,我将渲染它的子块base_app.html{% block page_content %} 块中的内容。所以我得到的网页不会包含与{% block page_app %} 块有关的任何内容。

    解决此问题的方法是将{% block page_app %} 中的base_app_main.html 中的信息冒泡到我们的base.html

    为此,我找到了 2 个解决方案:

    1 - 嵌套,或将base_app.html 修改为:

    {% extends "base.html" %}
    
    {% block page_content %}
    //html here
    {% block page_app %}
    {% endblock page_app %}
    {% endblock page_content %}
    

    在这种情况下,当base.html 被渲染时,它将从{% block page_content %} 块中获取所有信息,该块现在包含{% block page_app %} 块并成功渲染所有内容。

    2 - 修改base.html

    //link stylesheet
    
    {% block page_content %}
    {% endblock page_content %}
    
    {% block page_app %}
    {% endblock page_app %}
    
    //add bootstrap, jQuery and run scripts
    

    这将明确要求 base.html 渲染它的孩子的 {% block page_app %} 块并且也可以工作。

    --> 首选哪种方法?我不知道。显式方法 (2) 似乎更直接,但这也意味着如果您的 base.html 用于许多不同的项目,它将被很多块弄乱。而隐式 (1) 方法在 DRY 方面更好......也许你们中的一些人可以让我知道哪个是“标准”。

    【讨论】:

      【解决方案3】:

      父模板仅从匹配的{% block %}{% endblock %} 中的子模板获取内容。您的 base.html 只有一个 page_content 块,因此不包括 child 中的另一个块。您可以将 base.html 修改为如下所示:

      //link stylesheet
      
      {% block page_content %}
      {% endblock %}
      
      {% block page_app %}
      {% endblock page_app %}
      //add bootstrap, jQuery and run scripts
      

      【讨论】:

      • 我不明白你在说什么,在这种情况下,应该是子块base_app_main.html 应该从其父块获取内容并呈现它。所以我有`base_app_main.html`扩展{% extends "base_app.html"%},它实际上显示了{% block page_content %} //html here {% endblock page_content %}之间的代码但是它无法呈现{% block page_app %} //html i wanna display when I call render(request, 'base_app_main.html', context) {% endblock page_app %}块内实际定义的内容......
      猜你喜欢
      • 1970-01-01
      • 2017-05-15
      • 2019-01-04
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 2019-12-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多