在Django模板中复制数据的最佳方法是什么?
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>{% block title %}{% endblock %}</h1>
</body>
</html>
这是我的模板,大致上就是这样。h1标题总是和标题标签一样。上面的这段代码是不合法的,因为不能有两个同名的块。我该怎么处理这个问题,才能避免重复呢?
补充说明一下:我有很多从这个模板继承的子模板,所以为每个模板创建一个新的{{title}}变量并不是一个很好的解决办法。之前我设置成这样:
base.html:
<title>{% block title %}{% endblock %}</title>
然后在base_view.html(扩展自base.html):
<h1>{% block title %}{% endblock %}</h1>
接着在base_object.html(扩展自base_view.html):
{% block title %}my title goes here{% endblock %}
这样就能正常工作。我重新整理了我的模板,现在只有base.html和base_object.html。我该怎么才能恢复之前的功能呢?
4 个回答
{% extends "base.html" %}
{% with "Entry Title" as title %}
{% block title %}{{ title }}{% endblock %}
{% block h1 %}{{ title }}{% endblock %}
{% endwith %}
如果你真的很担心在视图中出现 title
这个内容,并且想要避免重复的话,这样做是可行的。
在base.html文件中:
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>{% block h1 %}{% endblock %}</h1>
</body>
接下来,创建一个新的“基础”层,叫做content_base.html(或者其他名字):
{% extends "base.html" %}
{% block h1 %}{% block title %}{% endblock %}{% endblock %}
现在,让你所有其他的模板都基于content_base.html。你在所有模板中的“title”块里写的内容,会同时出现在base.html中的“title”和“h1”块里。
看起来你的布局设计得不错。你有一个 base.html
模板,它定义了你应用中每个页面的基本结构和外观。还有一个 base_object.html
模板,它是基于这个基础模板扩展出来的。
你希望每个页面都有一个独特的标题和对应的 h1 标签(我想是这样)。实现这个的最好方法是在你的 base.html
模板中定义两个不同的区域。
<html>
<head>
<title>{% block title %}Default Title{% endblock %}</title>
</head>
<body>
<h1>{% block h1 %}{% endblock %}</h1>
</body>
</html>
在你的子模板中,如果你希望这两个区域的内容相同,就需要覆盖这两个区域。我知道你觉得这样有点反直觉,但这是因为 Django 处理模板继承的方式所决定的。
来源:Django 模板语言
最后要注意的是,在同一个模板中不能定义多个同名的
{% block %}
标签。这是因为一个块标签是双向的。也就是说,块标签不仅仅是提供一个可以填充的空洞,它还定义了填充这个空洞的内容。如果在一个模板中有两个同名的{% block %}
标签,那个模板的父模板就不知道该用哪个块的内容了。
子模板看起来是这样的:
{% extends "base.html" %}
{% block title %}Title{% endblock %}
{% block h1 %}Title{% endblock %}
如果这让你觉得困扰,你可以在视图中为每个对象设置标题,作为一个模板变量。
{% block title %}{{ title }}{% endblock %}
{% block h1 %}{{ title }}{% endblock %}
Django 尽量把逻辑放在模板层之外。通常,标题是从数据库动态获取的,所以在视图层获取和设置这些信息是最合适的。如果你想使用默认标题(可能是在 base.html
中设置的),你也可以把标题留空,或者从 django.contrib.sites
包中获取网站名称。
另外,{{ block.super }}
可能会很有用。这个可以让你把父块的内容和子块的额外内容结合起来。所以你可以在基础模板中定义一个标题,比如 "Stackoverflow.com",然后在子模板中设置
{% block title %}{{ block.super }} - Ask a Question{% endblock %}
这样就能得到一个像 "Stackoverflow.com - Ask a Question" 的标题。