Как лучше всего дублировать данные в шаблоне 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. Как мне вернуть эту функциональность?


person priestc    schedule 24.07.2009    source источник


Ответы (4)


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

person sixthgear    schedule 24.07.2009

В 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» во всех ваших шаблонах, войдет в блоки «title» и «h1» в base.html.

person hopti    schedule 17.03.2010
comment
Ой, но я полагаю, это сработает. - person mlissner; 10.01.2015
comment
работает! действенно и просто и в чем-то хакерское, но работает. - person benzkji; 10.05.2018

{% extends "base.html" %}

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

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

person Steve Losh    schedule 24.07.2009
comment
Это должен быть принятый ответ - person Jay D.; 03.06.2019

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

See also: How to repeat a "block" in a django template

person Corey Sunwold    schedule 24.07.2009
comment
Это не то, как следует использовать Django. - person Frank Crook; 24.07.2009
comment
@ Фрэнк Крук: Не хочешь объяснить? - person Corey Sunwold; 24.07.2009
comment
@csunwold: У меня действительно нет времени, иначе я бы просто ответил на вопрос. Короче говоря, вопрос исходит от человека, который принципиально не понимает, как работают блоки и наследование в системе шаблонов Django. Ваш ответ не проясняет для них это, вместо этого он полностью перескакивает через тему блоков и наследования и показывает пример, в котором они вообще не используются. - person Frank Crook; 24.07.2009
comment
+1: Используйте это все время. Работает отлично. - person S.Lott; 24.07.2009
comment
Другими словами, Фрэнк упомянул: статический контент никогда не должен определяться в представлениях. Они относятся к шаблонной области и должны быть там определены. - person igorsantos07; 27.11.2017