【问题标题】:Whats the best way to duplicate data in a django template? [duplicate]在 django 模板中复制数据的最佳方法是什么? [复制]
【发布时间】:2010-11-13 19:19:57
【问题描述】:
<html>
    <head>
        <title>{% block title %}{% endblock %}</title>
    </head>

    <body>
        <h1>{% block title %}{% endblock %}</h1>
    </body>
</html>

这是我的模板,或多或少。 h1 标题始终与标题标签相同。上面的 sn-p 代码是无效的,因为不能有两个同名的块。如何在不重复自己的情况下处理这个问题?


编辑澄清:我有大量从这个模板继承的子模板,因此为每个模板创建一个新的 {{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 我怎样才能恢复这个功能?

【问题讨论】:

    标签: python django django-templates


    【解决方案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

    【讨论】:

    • 这不是 Django 应该使用的方式。
    • @Frank Crook:需要解释一下吗?
    • @csunwold:我真的没有时间,或者我只是回答了这个问题。简而言之,这个问题来自对 Django 模板系统中的块和继承如何工作有根本误解的人。您的回答并没有为他们澄清这一点,而是完全跳过了块和继承的主题,并显示了一个根本不使用它们的示例。
    • +1:一直使用这个。效果很好。
    • 弗兰克提到的,换句话说:静态内容永远不应该在视图中定义。它们属于模板领域,应该定义。
    【解决方案2】:

    看起来您的布局很可靠。你有一个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 - Ask a Question”的标题

    【讨论】:

      【解决方案3】:
      {% extends "base.html" %}
      
      {% with "Entry Title" as title %}
          {% block title %}{{ title }}{% endblock %}
          {% block h1 %}{{ title }}{% endblock %}
      {% endwith %}
      

      如果您真的担心将title 排除在视图之外并且不重复自己的话,这可能会起作用。

      【讨论】:

      • 这应该是公认的答案
      【解决方案4】:

      在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”块中。

      【讨论】:

      • 哎呀,但我想它会工作的。
      • 有效!高效而简单,不知何故是一种黑客行为,但有效。
      猜你喜欢
      • 2010-09-05
      • 1970-01-01
      • 2010-09-16
      • 2012-05-18
      • 2012-05-15
      • 1970-01-01
      • 2010-09-06
      • 2011-05-09
      • 1970-01-01
      相关资源
      最近更新 更多