Шаблоны¶
Будучи веб фреймверком, Django позволяет динамически генерировать HTML. Самый распространенный подход - использование шаблонов. Шаблоны содержат статический HTML и динамические данные, рендеринг которых описан специальным синтаксисом. Пример использования шаблонов для создания HTML шаблонов можно найти в учебнике Часть 3.
Проект Django может быть настроен с одним или несколькими механизмами шаблонов (или даже без них, если вы не используете шаблоны). Django предлагает встроенные серверные части для своей собственной системы шаблонов, креативно названной языком шаблонов Django (DTL), а также для популярной альтернативы Jinja2. Серверные части для других языков шаблонов могут быть доступны у третьих сторон. Вы также можете написать свой собственный пользовательский интерфейс, см. Пользовательский шаблон
Django предоставляет стандартный API для загрузки и рендеринга шаблонов, незавимисо от используемого бэкенда. Загрузка включает в себя поиск шаблона по названию и предварительную обработку, обычно выполняется загрузка шаблона в память. Рендеринг означает передачу данных контекста в шаблон и возвращение строки с результатом.
Язык шаблонов Django – собственная система шаблонов Django. До Django 1.8 – это была единственная альтернатива. Это хорошая система шаблонов, но со своими особенностями. Если у вас нет причин использовать другую систему шаблон, используйте встроенную, особенно, если разрабатываете распространяемое приложение, содержащее шаблоны. Встроенные шаблоны Django, которые содержат шаблоны, например django.contrib.admin, используют систему шаблонов Django.
По историческим причинам поддержка шаблонов и встроенная система шаблонов Django находятся в одном пакете django.template.
Предупреждение
Система шаблонов не защищена от ненадежных авторов шаблонов. Например, сайт не должен позволять своим пользователям предоставлять свои собственные шаблоны, поскольку авторы шаблонов могут выполнять такие действия, как выполнение XSS-атак и доступ к свойствам переменных шаблона, которые могут содержать конфиденциальную информацию.
Язык шаблонов Django¶
Синтаксис¶
Об этом документе
Этот раздел описывает основы синтаксиса языка шаблонов Django. Подробности смотрите в полном описании.
Шаблон Django – это просто текстовый файл, или строка Python, которые следуют языку шаблонов Django. Определенные конструкции распознаются и интерпретируются шаблонизатором. Основные – это переменные и теги.
Шаблон рендерится с контекстом. Рендеринг заменяет переменные на их значения, которые ищутся в контексте, и выполняет теги. Все остальное выводится как есть.
Синтаксис языка шаблонов Django использует четыре конструкции.
Переменные¶
Переменные выводят значения из контекста, который является словарем.
Переменные заключаются в {{ и }} следующим образом:
My first name is {{ first_name }}. My last name is {{ last_name }}.
В контексте {'first_name': 'John', 'last_name': 'Doe'} этот шаблон отображается как:
My first name is John. My last name is Doe.
Поиск по словарю, поиск по атрибутам и поиск по индексу списка реализованы с помощью точечной записи:
{{ my_dict.key }}
{{ my_object.attribute }}
{{ my_list.0 }}
Если значение переменной является вызываемый объект, шаблонизатор вызовет его без аргументов и подставит результат.
Фильтры¶
Фильтры преобразуют переменные и аргументы тегов.
Они выглядят так:
{{ django|title }}
В контексте {'django': 'веб-фреймворк для перфекционистов с соблюдением сроков'} этот шаблон отображается как:
The Web Framework For Perfectionists With Deadlines
Некоторые фильтры принимают аргумент:
{{ my_date|date:"Y-m-d" }}
Ознакомьтесь со списком встроенных фильтров и руководством по созданию фильтра.
Комментарии¶
Комментарии выглядят следующим образом:
{# this won't be rendered #}
Тег {% comment %} позволяет добавлять многострочные комментарии.
Компоненты¶
Об этом документе
Это обзор API языка шаблонов Django. Подробности смотрите в полном описании API.
Engine¶
django.template.Engine инкапсулирует шаблонизатор Django. Главная причина использовать непосредственно Engine – использовать шаблонизатор Django все проекта Django.
django.template.backends.django.DjangoTemplates – адаптер django.template.Engine для API шаблонов Django.
Шаблон¶
django.template.Template представляет собой скомпилированный шаблон. Шаблоны получаются с помощью Engine.get_template() или Engine.from_string().
django.template.backends.django.Template – адаптер django.template.Template для API шаблонов Django.
Контекст¶
django.template.Context помимо данных контекста содержит некоторые метаданные. Он передается Template.render() для рендеринга шаблона.
django.template.RequestContext – дочерний класс Context, который содержит текущий HttpRequest и выполняет процессоры контекста.
API шаблонов Django не содержит аналога. Данные контекста передаются как dict, а текущий HttpRequest передается отдельно при необходимости.
Загрузчики¶
Загрузчики шаблонов отвечают за их поиск, загрузку и создание объекта Template.
Django предоставляет несколько встроенных загрузчиков шаблонов и поддерживает собственные загрузчики.
Процессоры контекста¶
Процессоры контекста – это функции, которые принимают текущий HttpRequest, и возвращают dict данными, которые будут добавлены в контекст.
Используются для добавления данных, которые необходимы при рендеринге различных шаблонов, чтобы избежать дублирования кода в представлениях.
Django предоставляет множество встроенных процессоров контекста. Создать собственный процессор контекста так же просто, как и создать функцию.
Поддержка систем шаблонов¶
Настройки¶
Шаблоны можно настроить с помощью настройки TEMPLATES. Это список, который содержит настройки для систем шаблонов. По умолчанию настройка пустая. settings.py, сгенерированный командой startproject, содержит более полезное значение:
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
# ... some options here ...
},
},
]
BACKEND путь для импорта Python к классу бэкенда шаблонов. Встроенные бэкенды это django.template.backends.django.DjangoTemplates и django.template.backends.jinja2.Jinja2.
Т.к. большинство систем шаблонов загружают шаблоны с файлов, настройки содержат:
DIRS, которая содержим список каталогов с шаблонами. Бэкенд ищет в них шаблон в указанном порядке.APP_DIRSуказывает бэкенду искать ли шаблоны в установленных приложениях. Каждый бэкенд определяет определенное название для каталога с шаблонами в приложении.
Хотя это и не особо полезно, вы можете настроить несколько экземпляров одной системы шаблонов. В этом случае необходимо указать уникальные значения NAME для каждого экземпляра.
OPTIONS содержит настройки специфические для бэкенда.
Использование¶
Модуль django.template.loader предоставляет две функции для загрузки шаблонов.
- get_template(template_name, using=None)¶
Эта функция загружает шаблон с указанным названием и возвращает объект
Template.Возвращаемое значение зависит от используемого бэкенда т.к. каждый бэкенд использует свой класс
Template.get_template()пытается загрузить шаблон каждым из бэкендов, пока шаблон не будет загружен. Если шаблон не найден, будет вызвано исключениеTemplateDoesNotExist. Если шаблон найден, но синтаксис не верен, будет вызваноTemplateSyntaxError.Как шаблоны ищутся и загружаются, зависит от используемого бэкенда шаблонов и его настроек.
Если вы хотите использовать конкретный бэкенд, передайте его название из
NAMEв аргументеusing.
- select_template(template_name_list, using=None)¶
select_template()как иget_template(), но принимает список названий шаблонов. Пытается загрузить по очереди каждый из шаблонов, возвращает первый загруженный.
Если не удалось загрузить шаблон, вызываются исключения, описанные в django.template:
- exception TemplateDoesNotExist(msg, tried=None, backend=None, chain=None)¶
Это исключение вызывается, если шаблоне не был найден. Принимает дополнительные параметры, которые отображаются на странице ошибки:
backendБэкенд шаблонов, который вызывал исключение.
triedСписок источников шаблонов, которые проверялись при поиске шаблона. Состоит из списка кортежей вида
(origin, status), гдеorigin– это объект Origin, аstatus– строка, которая описывает ошибку.chainСписок промежуточных ошибок
TemplateDoesNotExist, которые были вызваны при поиске шаблона. Используется функцией, напримерget_template(), которая пытается загрузить шаблон, используя разные бэкенды.
- exception TemplateSyntaxError(msg)¶
Это исключение вызывается, если шаблон найден, но содержит ошибки.
Объекты Template, которые возвращают get_template() и select_template(), должны содержать метод render() со следующей сигнатурой:
- Template.render(context=None, request=None)¶
Рендерит шаблон с переданным контекстом.
Если
contextпередан, это должен бытьdict. Если не передан, используется пустой контекст.Если передан
request, это должен быть экземплярHttpRequest. Шаблонизатор должен добавить его в шаблон, как и CSRF токен. Как это должно происходит определяет шаблонизатор.
Пример алгоритма поиска шаблона. Возьмем следующую настройку TEMPLATES:
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [
"/home/html/example.com",
"/home/html/default",
],
},
{
"BACKEND": "django.template.backends.jinja2.Jinja2",
"DIRS": [
"/home/html/jinja2",
],
},
]
Если вызвать get_template('story_detail.html'), Django будет искать следующие файлы:
/home/html/example.com/story_detail.html(шаблонизатор'django')/home/html/default/story_detail.html(шаблонизатор'django')/home/html/jinja2/story_detail.html(шаблонизатор'jinja2')
Если вызвать select_template(['story_253_detail.html', 'story_detail.html']), Django бдудет искать:
/home/html/example.com/story_253_detail.html(шаблонизатор'django')/home/html/default/story_253_detail.html(шаблонизатор'django')/home/html/jinja2/story_253_detail.html(шаблонизатор'jinja2')/home/html/example.com/story_detail.html(шаблонизатор'django')/home/html/default/story_detail.html(шаблонизатор'django')/home/html/jinja2/story_detail.html(шаблонизатор'jinja2')
Если Django находит шаблон, поиск останавливается.
Используйте django.template.loader.select_template() для большей гибкости.
Вы можете использовать select_template() для гибкой загрузки шаблонов. Например, вы написали новость и хотите использовать другой шаблон для некоторых новостей. Вы можете использовать select_template(['story_%s_detail.html' % story.id, 'story_detail.html']). Это позволить создать отдельный шаблон для определенных новостей, а для всех остальных использовать шаблон по умолчанию.
Мы советуем хранить шаблоны в подкаталогах в каталогах с шаблонами. Следует создать подкаталог для каждого приложения Django, в котором вы можете хранить шаблоны в различных подкаталогах, если это необходимо.
Хранить все шаблоны в корневом каталоге может привести к хаосу в шаблонах.
Чтобы загрузить каталог из подкаталога, просто используйте слэш:
get_template("news/story_detail.html")
При использовании настроек TEMPLATES, приведенных выше, Django будет искать следующие шаблоны:
/home/html/example.com/news/story_detail.html(шаблонизатор'django')/home/html/default/news/story_detail.html(шаблонизатор'django')/home/html/jinja2/news/story_detail.html(шаблонизатор'jinja2')
Django предоставляет несколько вспомогательных функций для работы с шаблонами.
- render_to_string(template_name, context=None, request=None, using=None)¶
render_to_string()загружает шаблон как иget_template(), и вызывает методrender(). Принимает следующие аргументы.template_nameНазвание шаблона, который будет загружен и выполнен. Если указать список шаблонов, для поиска шаблонов Django будет использовать
select_template()вместоget_template().contextdict, который будет использовать как контекст при рендеринге шаблона.requestНеобязательный
HttpRequest, который будет использоваться при рендеринге шаблона.usingДополнительный механизм шаблонов
NAME. Поиск шаблона будет ограничен этим движком.
Например:
from django.template.loader import render_to_string rendered = render_to_string("my_template.html", {"foo": "bar"})
Смотрите также render() и render_to_response(), которые вызывают render_to_string() и передают результат в HttpResponse, который можно вернуть из представления.
Вы можете использовать шаблонизатор непосредственно:
Встроенные бэкенды¶
- class DjangoTemplates¶
Укажите 'django.template.backends.django.DjangoTemplates' в BACKEND, чтобы использовать шаблонизатор Django.
Если APP_DIRS равна True, DjangoTemplates будет искать шаблоны в подкаталогах templates установленных приложений. Такое название используется для обратной совместимости.
DjangoTemplates принимает следующие параметры OPTIONS:
'autoescape': логическое значение, которое определяет, включено ли автоматическое экранирование HTML.По умолчанию содержит пустой список.
Предупреждение
Устанавливайте значение «False» только в том случае, если вы отображаете шаблоны, отличные от HTML!
'context_processors': список путей Python, который указывают на процессоры контекста, которые добавляют дополнительные переменные в контекст при рендеринге шаблона в процессе обработки запроса. Процессоры контекста – это функции, или другие вызываемые объекты, которые принимают объект запроса и возвращаютdictзначений, который будут добавлены в контекст.По умолчанию содержит пустой список.
Подробности смотрите в описании
RequestContext.'debug': булево значение, которое включает/выключает отладку шаблонов. ПриTrueбудет отображаться страница с отладочной информацией, если возникнет ошибка при рендеринге шаблона. Страница показывает часть шаблона, которая вызвала ошибку.По умолчанию равна значению
DEBUG.'loaders': список путей Python к загрузчикам шаблонов. Каждый классLoaderзнает как загрузить шаблон из определенного источника. Можно использовать кортеж вместо строки. Первым элементом должен быть путь кLoader, последующие элементы передаются вLoaderпри инициализации.Значение по умолчанию зависит от значений
DIRSиAPP_DIRS.Подробности смотрите в Типы загрузчиков.
'string_if_invalid': строка, которая будет использоваться для неправильных (например, с опечаткой) переменных в шаблоне.По умолчанию пустая строка.
Подробности смотрите в Как обрабатываются неправильные переменные.
'file_charset': кодировка, которая используется при чтении файла шаблона с диска.По умолчанию содержит пустой список.
'libraries': словарь библиотек тегов, которые зарегистрированы для бэкенда. Состоит из названия библиотеки и пути для импорта. Позволяет добавлять новые библиотеки, или поменять название для существующих. Например:OPTIONS = { "libraries": { "myapp_tags": "path.to.myapp.tags", "admin.urls": "django.contrib.admin.templatetags.admin_urls", }, }
Библиотеки могут быть загружены с помощью тега
{% load %}, в котором нужно указать соответствующий ключ словаря.'builtins': список путей для импорта библиотек тегов, которые будут автоматически загружены и добавлены к встроенным тегам и фильтрам. Например:OPTIONS = { "builtins": ["myapp.builtins"], }
Теги и фильтры из этих библиотек могу быть использованы без вызова
{% load %}.
- class Jinja2¶
Для использования необходимо установить Jinja2:
$ python -m pip install Jinja2
...\> py -m pip install Jinja2
Укажите 'django.template.backends.jinja2.Jinja2' в BACKEND для настройки шаблонизатора Jinja2.
Если APP_DIRS равна True, Jinja2 будет искать шаблоны в подкаталоге ``jinja2``установленных приложений.
Самой важной настройкой в OPTIONS является 'environment'. Это путь для импорта функции, или другого вызываемого объекта, которая возвращает Jinja2. По умолчанию 'jinja2.Environment'. Django вызывает функцию и передает другие параметры как именованные аргументы. Также Django указывает значения по умолчанию для некоторых параметров Jinja2:
'autoescape':True'loader': загрузчик соответствующий настройкамDIRSиAPP_DIRS'auto_reload':settings.DEBUG'undefined':DebugUndefined if settings.DEBUG else Undefined
DjangoTemplates принимает следующие параметры OPTIONS:
'context_processors': список путей Python, который указывают на процессоры контекста, которые добавляют дополнительные переменные в контекст при рендеринге шаблона в процессе обработки запроса. Процессоры контекста – это функции, или другие вызываемые объекты, которые принимают объект запроса и возвращаютdictзначений, который будут добавлены в контекст.По умолчанию содержит пустой список.
Использование контекстных процессоров с шаблонами Jinja2 не рекомендуется.
Контекстные процессоры полезны с шаблонами Django, поскольку шаблоны Django не поддерживают вызов функций с аргументами. Поскольку в Jinja2 такого ограничения нет, рекомендуется поместить функцию, которую вы будете использовать в качестве обработчика контекста, в глобальные переменные, доступные для шаблона, используя jinja2.Environment, как описано ниже. Затем вы можете вызвать эту функцию в шаблоне:
{{ function(request) }}
Некоторые процессоры контекста шаблонов Django возвращают фиксированное значение. Для шаблонов Jinja2 этот уровень косвенности не обязателен, поскольку вы можете добавлять константы непосредственно в jinja2.Environment.
Исходный вариант использования для добавления процессоров контекста для Jinja2 включал:
Выполнение дорогостоящих вычислений, зависящих от запроса.
Нужен результат в каждом шаблоне.
Использование результата несколько раз в каждом шаблоне.
Если все эти условия не соблюдены, передача функции в шаблон больше соответствует дизайну Jinja2.
Настройки по умолчанию намерено сокращены до минимума. Jinja2 не создает окружение заточенное под Django. Шаблонизатор ничего не знает про процессоры контекста Django, фильтры и теги. Чтобы использовать API Django, необходимо настроить окружение шаблонизатора.
Например, вы можете создать следующий myproject/jinja2.py:
from django.templatetags.static import static
from django.urls import reverse
from jinja2 import Environment
def environment(**options):
env = Environment(**options)
env.globals.update(
{
"static": static,
"url": reverse,
}
)
return env
и указать в настройке 'environment' 'myproject.jinja2.environment'.
Теперь вы можете использовать в шаблонах Jinja2:
<img src="{{ static('path/to/company-logo.png') }}" alt="Company Logo">
<a href="{{ url('admin:index') }}">Administration</a>
Концепция тегов и фильтров существует как в шаблонах Django, так и Jinja2, но используется по разному. Так как Jinja2 позволяет передавать аргументы при вызове функций и методов, многие вещи, для которых необходим тег или фильтр в шаблонах Django, можно использовать напрямую в шаблонах Jinja2, как это делается в примере выше. Глобальное пространство имен Jinja2 не требует процессоров контекста. Язык шаблонов Django не имеет аналогов тестов Jinja2.