Джанго: расширяет или включает? - PullRequest
12 голосов
/ 24 февраля 2010

У меня и моего друга небольшой спор. В моем текущем проекте Django я создал файл с именем menu.html, который будет содержать набор ссылок, настроенных и отформатированных в виде списка. Вместо того, чтобы вручную жестко кодировать меню на каждой странице, в настоящее время я включаю меню, используя следующий код Django / Python:

{% include 'menu.html' %}

Однако, мой друг предполагает, что это неправильный способ сделать это. Он сказал, что мне нужно использовать extends вместо include, а затем определить контент, что-то вроде этого:

{% extend 'menu.html' %}
{% block content %}
The rest of my content here.
{% endblock %}

Это немного лишнего кода. Это действительно имеет значение, какой я использую? Я бы предпочел использовать первое.

Ответы [ 3 ]

13 голосов
/ 24 февраля 2010

Да, это важно. Прежде всего extends может встречаться только в самой первой строке файла. Во-вторых, include помещает и помещает объект контекста в стек разрешения, что означает, что значение, созданное в контексте во время включения, выйдет из области видимости при возврате.

Мое правило: создавать base.html файлы шаблонов, которые определяют общую структуру вашего сайта и использовать либеральные суммы {% block foo %} в критических областях. Затем все ваши другие шаблоны extends база (или что-то, что само расширяет базу), и вы заменяете эти блоки по мере необходимости.

include, с другой стороны, подходит для инкапсуляции вещей, которые вам может понадобиться использовать более чем в одном месте, возможно, даже на одной странице.

Обновление:

Я использовал свою собственную библиотеку template_tags так долго, что забыл, что в языке шаблонов Django все еще есть большие пробелы в функциональности. Данный тег взят из раннего фрагмента django под названием expr, который я сильно отредактировал и расширил. Вы можете сказать, например, {% expr 'Fred' as name %} (или любое допустимое выражение Python), и результат будет сохранен в слоте 'name' в текущем контексте . Если это происходит в шаблоне included, значение name будет отображаться при выходе из файла шаблона.

Этого можно добиться с помощью тега {% with %}, но expr дает мне гораздо большую гибкость, включая выполнение произвольно сложных вызовов. Первоначально это возникло, когда нужно было создавать сложные кэшированные объекты, которые требовали дорогостоящих взаимодействий с СУБД, которые не могли быть выполнены в представлении, их нужно было вызывать в самом шаблоне.

Напишите мне (в моем профиле), если вам нужно углубиться в это.

3 голосов
/ 24 февраля 2010

(его друг)

На самом деле я имел в виду определение base.html, чтобы вы могли наследовать базовый шаблон, совместимый с несколькими общими разделами, в этот элемент входит doctype, элемент html определяет 3 блока для содержимого и навигации и необязательную область для переопределения / вставки сценария / элементы ссылки в голове.

<!doctype>
<html>
<head>
{%block extrahead %} {%endblock %}
</head>
{%block nav %}
<nav>
  <ul>
    <li>home</li>
  </ul>
</nav>
<div id="content">
{% endblock %}
{%block content %}
{% endblock %}
</div>
</html>

Тогда вы можете определить homepage.html:

{% extends "base.html" %}

{% block content %}
homepage content
{% endblock %}

homepage.html будет тогда иметь навигацию, потому что она расширяет base.html.

2 голосов
/ 24 февраля 2010

В этом случае размещение меню в base.html и расширение от этого представляется более разумным.

including отлично подходит для разбиения сложного шаблона и повторного использования этих кусков.

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

Здесь Я использую разные шаблоны для обычных и ajax-запросов. Но использование include позволяет мне повторно использовать большинство частей в обоих шаблонах

...