什么是在django模板中复制数据的最佳方法?

时间:2009-07-24 16:29:25

标签: python django django-templates

<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 个答案:

答案 0 :(得分:21)

在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。无论你在所有模板中的块“标题”中放置什么,都会进入base.html中的“title”和“h1”块。

答案 1 :(得分:8)

看起来你的布局很稳固。您有一个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中处理模板继承的方式,这是必要的。

来源:The Django template language

  

最后,请注意,您无法在同一模板中定义多个具有相同名称的{% 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 - 提出问题”这样的标题

答案 2 :(得分:8)

{% extends "base.html" %}

{% with "Entry Title" as title %}
    {% block title %}{{ title }}{% endblock %}
    {% block h1 %}{{ title }}{% endblock %}
{% endwith %}

如果您真的担心将title排除在视图之外而不是重复自己,那么这可能会有用。

答案 3 :(得分:1)

将变量传递给模板,也许称为标题。然后用{{title}}替换标题栏。要将其传递到视图中的模板,请确保您拥有:

def myview(request):
    t = loader.get_template("mypage.html")
    title = "My Title"
    c = Context({"title" : title })
    HttpResponse(t.render(c))

然后在您的模板中,您将拥有:

<html>
<head>
    <title>{{ title }}</title>
</head>

<body>
    <h1>{{ title }}}</h1>
</body>

另请参阅:How to repeat a "block" in a django template