Django: расширяет или включает?
У моего друга и меня небольшой спор. В моем текущем проекте Django я создал файл с именем menu.html, который будет содержать кучу ссылок, настроенных и отформатированных в список. Вместо ручного жесткого кодирования меню на каждую страницу я в настоящее время включаю меню, используя следующий код Django/Python:
{% include 'menu.html' %}
Однако мой друг говорит, что это неправильный способ сделать это. Он сказал, что мне нужно использовать extends вместо include, а затем определить контент, что-то вроде этого:
{% extend 'menu.html' %}
{% block content %}
The rest of my content here.
{% endblock %}
Это немного дополнительного кода. Действительно ли имеет значение, что я использую? Я бы предпочел использовать первое.
Ответы
Ответ 1
Да, это важно. Прежде всего extends
может появляться только в первой строке файла. Во-вторых, include
выталкивает и выдает контекстный объект в стеке разрешения, что означает, что значение, созданное в контексте, в то время как в include будет выходить из области видимости, когда оно возвращается.
Мое правило: создайте файлы шаблонов base.html
, которые определяют общую структуру вашего сайта и используют в крутых зонах либеральные суммы {% block foo %}
. Затем все ваши другие шаблоны extends
базы (или что-то, что сама расширяет базу), и вы заменяете эти блоки по мере необходимости.
include
, с другой стороны, хорош для инкапсуляции вещей, которые вам могут понадобиться использовать в нескольких местах, возможно, даже на одной странице.
Update:
Я использую свою собственную библиотеку template_tags
так долго, что забыл, что язык шаблонов Django по-прежнему имеет существенные недостатки в функциональности. Тег, о котором идет речь, относится к раннему фрагменту django под названием expr
, который я сильно отредактировал и расширил. Вы можете сказать, например, {% expr 'Fred' as name %}
(или любое действительное выражение Python), и он сохранит результат в слоте "name" в текущем Контексте. Если это происходит в шаблоне included
, при выходе из файла шаблона будет выведено значение name
.
Вы можете добиться этого с помощью тега {% with %}
, но expr
дает мне гораздо большую гибкость, в том числе выполнение произвольно сложных вызовов. Это изначально появилось при создании сложных кешированных объектов, требующих дорогостоящих взаимодействий СУБД, которые не могли быть реализованы в представлении, их нужно было вызвать в самом шаблоне.
Напишите мне (в моем профиле), если вам нужно углубиться в это.
Ответ 2
(его друг)
То, что я на самом деле имел в виду, это определение base.html
, чтобы вы могли наследовать базовый шаблон, совместимый с несколькими родовыми разделами, в том числе элемент doctype, html, который определяет 3 блока для содержимого и навигацию и дополнительную область для переопределения/вставки script/link в голове.
<!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
.
Ответ 3
В этом случае размещение меню в base.html
и продолжение от него кажется более понятным.
including
отлично подходит для разделения сложного шаблона и повторного использования этих фрагментов.
скажем, вы используете тот же стиль списка в разных местах сайта, но вы отправляете ему другой запрос. так как вы так же называете запросы, вам нужно только один раз написать код шаблона.
Здесь Я использую разные шаблоны для обычных и ajax-запросов. Но используя include, позвольте мне повторно использовать большинство частей в обоих шаблонах