django:在包含的模板中使用块

Xun*_*ang 37 django django-templates

我有一些html结构,可以在很多不同的地方重用.它与整体模板不同,所以我不能扩展它,它也可以用来包含复杂的内容,所以我不认为将它定义为模板标签做得很好.下面是一些描述我想要的结果的伪代码,当使用template_level2.html时,您可以通过调用其中的块轻松地将内容放入reusable_pattern_template.如果我使用此代码,则您在template_level_2.html的"实际内容"中所写的内容将不会显示.我应该怎么处理这个?

base.html文件

<html>
<head></head>
<body>
{% block content %}{% endblock %}
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

template_level1.html

{% extends 'base.html' %}
{% block content %}
  Something here...
  {% include 'reusable_pattern_template.html' %}
  Something else here...
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

reusable_pattern_template.html

<div>
  <div>
    <div>
      {% block local_content %}{% endblock %}
    </div>
   </div>
</div>
Run Code Online (Sandbox Code Playgroud)

template_level2.html

{% extends 'template_level1.html' %}
{% block local_content %}
  Actual content here...
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

更新: 对不起,template_level2.html中的扩展有一些拼写错误,我刚刚更正了.

它可能不是很清楚,但上面的代码更像是一个描述我想要的结果的伪代码.简而言之,

  • 我想在我的模板中包含一些可重复使用的html模式.
  • 这些模式就像盒子一样,你可以把整个html内容放在其中.因此,对于我的目的,上下文变量可能有点过于有限

Chr*_*att 54

Django不处理包含文件中的块.

include标记应该被视为"渲染此子模板并包含HTML"的实现,而不是"解析此子模板并将其内容包含在内,就好像它是父类的一部分".这意味着包含的模板之间没有共享状态 - 每个包含都是完全独立的渲染过程.(Django模板标签文档)

  • 有用的解释,但_is_有一个标签或其他方法来做OP希望的?我也希望能够包含模板,并且仍然能够使用模板继承 (8认同)
  • 但是,视图中的变量仍然是共享和解析的. (7认同)
  • @Chris Pratt 如果我想在脚本标签中包含一个具有一些“模型绑定”JS 行为的页面,并且我不希望 &lt;script&gt; 标签散落在各处([检查这个问题](http:/ /stackoverflow.com/questions/32721155/django-templates-including-pages-that-injects-code-into-parent-block))?我认为在这个场景中使用 `include` 很适合当前的定义。 (2认同)
  • 2021年,有办法处理包含文件中的块吗? (2认同)

hwj*_*wjp 10

我遇到了这个问题,最终得到了以下妥协,希望其他人可能会觉得它有用。它依赖于with在子模板中使用块。

base.html想要重用一个通用的nav.html包含,但定义一些块,其中nav.html中的变量可能会被子模板覆盖。

<!-- base.html: -->
<html>
  [...]
  <nav class="desktop">
    {% block desktop_nav %}
      {% include "includes/nav.html" %}
    {% endblock %}
  </nav>
  [...]
  <nav class="mobile">
    {% block mobile_nav %}
      {% include "includes/nav.html" %}
    {% endblock %}
  </nav>
  [...]
Run Code Online (Sandbox Code Playgroud)

默认情况下selected,包含模板依赖于一个名为 的变量,base.html未定义该变量:

<!--includes/nav.html:-->
<a href="/about/" class="{% if selected == 'about' %}selected{% endif %}">About</a>
<a href="/people/" class="{% if selected == 'people' %}selected{% endif %}">People</a>
<a href="/contact/" class="{% if selected == 'contact' %}selected{% endif %}">Contact</a>
Run Code Online (Sandbox Code Playgroud)

但是子页面可以按如下方式覆盖该值:

<!--about.html:-->
{% extends "base.html" %}
{% block desktop_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %}
{% block mobile_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %}
Run Code Online (Sandbox Code Playgroud)

所以,并不完美,我仍然必须有两个单独的块并使用这些with块两次,但它确实允许我覆盖include父模板中块中的变量。


Umu*_*acı 5

看来最终的模板正在尝试扩展自身(如果它在引号中)

你真的不需要那么复杂。实际上要简单得多。

基本模板应包含模板的骨架,然后您可以对其进行扩展以进行自定义。对于您不想包含在每个视图中的可重用代码块,请include在适当的情况下使用它们,但不要在包含的文件中使用任何block,extends或语句。includeDjango 不会解析这些,但context variable仍然可以使用从视图传递的内容。