Каков наилучший способ дублирования данных в шаблоне django?

<html>
    <head>
        <title>{% block title %}{% endblock %}</title>
    </head>

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

Это мой шаблон, более или менее. Заголовок h1 всегда совпадает с тегом заголовка. Вышеприведенный фрагмент кода недействителен, поскольку не может быть двух блоков с тем же именем. Как я могу справиться с этим, не повторяя себя?


edit, чтобы уточнить: у меня есть тонна дочерних шаблонов, которые наследуются от этого одного шаблона, поэтому создание новой переменной {{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 %}

и он как-то работал. Я реорганизовал свои шаблоны, поэтому theres просто base.html и base_object.html. Как я могу вернуть эту функциональность?

Ответ 1

Похоже, ваш макет прочен. У вас есть шаблон 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 - Задайте вопрос"

Ответ 2

В 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" и "h1" в base.html.

Ответ 3

{% extends "base.html" %}

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

Это может сработать, если вы действительно беспокоитесь о том, чтобы оставить title вне взглядов и не повторять себя.

Ответ 4

Передайте переменную в ваш шаблон, возможно, названный заголовок. Затем замените заголовок блоком {{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>

См. также: Как повторить блок " в шаблоне django