我的结构中我的基本模板中的(% block heading %}
通常有一个页面标题:
base.html文件
<h2>{% block heading %}{% endblock %}</h2>
大多数时候,我会通过扩展基础的模板传递这样的标题:
延伸-base.html文件
{% block heading %}Super Cool Page!{% endblock %}
但是,对于特殊页面,我不希望页面标题为:
延伸碱基special.html
{% block heading %}{% endblock %}
理想情况下,这应排除<h2>
标记。现在,我可以让所有扩展模板都包含<h2>
标记,但这违反了DRY,因为每个页面都应该具有页面级标题的相同元素。我更喜欢做的是(这似乎不起作用):
基prefered.html
{% if heading %}
<h2>{% block heading %}{% endblock %}</h2>
{% endif %}
这在模板级别上是否可行,或者我是否需要填写视图?
答案 0 :(得分:30)
你可以双重包装
{% block noheader %}
<h2>{% block header %}Super Cool Page!{% endblock header %}</h2>
{% endblock noheader %}
在没有标题的页面上
{% block noheader %}{% endblock %}
答案 1 :(得分:4)
这样做:
<h2>{% block heading %}{% endblock %}</h2>
{% block heading %}{% endblock %}
然后扩展第一个或第二个模板。我相信这应该是最简单的方法。
顺便说一下。写下:
{% if heading %}
你实际上要求在名为'heading'的上下文中元素的布尔值。 django标记语言的元素不在上下文中,因此您不能要求它们。你可以写一个标签,为上下文增加一些东西,我曾经需要这样的东西并使用它,但我不相信这是去这里的方式。上面的解决方案应该工作(我没有机器检查这个),这是IMNSHO的最佳方式。
答案 2 :(得分:1)
Afaik还没有真正好的和简单的解决方案。除了czarchaic提供的选项之外,您还可以按Jarret Hardie's answer到"How to test for use of a django template block?"中所述编写自己的模板标记。但是,最好和最优雅的方式是{% capture as ... %}
模板标记 - 遗憾的是它还没有实现:https://code.djangoproject.com/ticket/6378
答案 3 :(得分:1)
我知道我迟到了,但对于那些(像我一样)仍在寻找解决方案的人来说,这是我的:
我创建了一个自定义 TemplateBackend,它将给定模板中每个块的名称放在名为“FILLED_BLOCKS”的上下文变量中。
这是代码:(注意:如果您多次扩展模板,它可能不起作用,但我想您可以通过添加一些递归或其他东西轻松解决此问题。这不是我需要的)< /p>
from django.template.backends.django import DjangoTemplates, Template, reraise, TemplateDoesNotExist
from django.template.context import make_context
from django.template.engine import Engine
from django.template.loader_tags import ExtendsNode
class CustomBackend(DjangoTemplates):
def from_string(self, template_code):
return CustomTemplate(self.engine.from_string(template_code))
def get_template(self, template_name):
try:
return CustomTemplate(self.engine.get_template(template_name), self)
except TemplateDoesNotExist as exc:
reraise(exc, self)
class CustomTemplate(Template):
def get_filled_blocks(self):
nodes = self.template.nodelist.get_nodes_by_type(ExtendsNode)
if len(nodes) == 0:
return []
blocks = []
for node in nodes:
for block in node.blocks.values():
if len(block.nodelist) != 0:
blocks.append(block.name)
return blocks
def render(self, context=None, request=None):
context['FILLED_BLOCKS'] = self.get_filled_blocks()
context = make_context(context, request, autoescape=self.backend.engine.autoescape)
try:
return self.template.render(context)
except TemplateDoesNotExist as exc:
reraise(exc, self.backend)
只需将此文件的路径放在 TEMPLATES['BACKEND'] 处的 settings.py 中
像这样在您的模板中使用它:
{% if 'heading' in FILLED_BLOCKS %}
<h2>{% block heading %}{% endblock %}</h2>
{% endif %}