0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Веб-приложение состоит из веб-страниц. Даже если приложение реализует большую часть интерфейса пользователя с помощью JavaScript, домашняя страница все равно отдается сервером. Да и ситуации, когда страничный сайт хорошо решает поставленные задачи, возникают часто. Поэтому подсистема шаблонизации остается важной частью full-stack фреймворков.</p>
1
<p>Веб-приложение состоит из веб-страниц. Даже если приложение реализует большую часть интерфейса пользователя с помощью JavaScript, домашняя страница все равно отдается сервером. Да и ситуации, когда страничный сайт хорошо решает поставленные задачи, возникают часто. Поэтому подсистема шаблонизации остается важной частью full-stack фреймворков.</p>
2
<p>В этом уроке разберем, что такое шаблонизация, и как на ее основе Django формирует HTML-страницы.</p>
2
<p>В этом уроке разберем, что такое шаблонизация, и как на ее основе Django формирует HTML-страницы.</p>
3
<h2>Язык шаблонизации</h2>
3
<h2>Язык шаблонизации</h2>
4
<p><strong>Шаблон</strong>- это почти готовый текстовый документ, в котором все неизменные части текста представлены как есть. А изменяемая часть описана на некотором языке с ветвлениями, условиями и циклами. Они позволяют преобразовать данные в подходящее представление. Этот язык называют<strong>языком шаблонизации</strong>или<strong>templating language</strong>.</p>
4
<p><strong>Шаблон</strong>- это почти готовый текстовый документ, в котором все неизменные части текста представлены как есть. А изменяемая часть описана на некотором языке с ветвлениями, условиями и циклами. Они позволяют преобразовать данные в подходящее представление. Этот язык называют<strong>языком шаблонизации</strong>или<strong>templating language</strong>.</p>
5
<p>На уровне шаблона разделяется ответственность. Шаблон страницы знает, как отобразить данные в виде HTML. А сами данные не зависят от этого представления и могут быть представлены по-разному разными шаблонами. По данным вообще нельзя сказать, что они будут представлены в виде HTML. Шаблонизатор возводит барьер абстракции.</p>
5
<p>На уровне шаблона разделяется ответственность. Шаблон страницы знает, как отобразить данные в виде HTML. А сами данные не зависят от этого представления и могут быть представлены по-разному разными шаблонами. По данным вообще нельзя сказать, что они будут представлены в виде HTML. Шаблонизатор возводит барьер абстракции.</p>
6
<p>Чтобы из кода, который формирует данные, не нужно было программировать отображение, у шаблонизатора есть свой язык программирования отображения. А для того, чтобы не было соблазна прямо в шаблоне получать данные, этот язык сделан с ограниченными возможностями.</p>
6
<p>Чтобы из кода, который формирует данные, не нужно было программировать отображение, у шаблонизатора есть свой язык программирования отображения. А для того, чтобы не было соблазна прямо в шаблоне получать данные, этот язык сделан с ограниченными возможностями.</p>
7
<p>В Django шаблонизация проработана достаточно глубоко. Есть встроенный шаблонизатор, можно использовать сторонние шаблонизаторы вроде Jinja2 и можно сочетать несколько шаблонизаторов в одном проекте. Это удобно, когда некоторые шаблоны достаются в наследство, либо когда мы переезжаем с одного шаблонизатора на другой.</p>
7
<p>В Django шаблонизация проработана достаточно глубоко. Есть встроенный шаблонизатор, можно использовать сторонние шаблонизаторы вроде Jinja2 и можно сочетать несколько шаблонизаторов в одном проекте. Это удобно, когда некоторые шаблоны достаются в наследство, либо когда мы переезжаем с одного шаблонизатора на другой.</p>
8
<p>Чтобы шаблон превратить в результат, Django использует бэкенды. Встроенных бэкенда два: DjangoTemplates и Jinja2. Сторонние пакеты могут предоставлять свои бэкенды.</p>
8
<p>Чтобы шаблон превратить в результат, Django использует бэкенды. Встроенных бэкенда два: DjangoTemplates и Jinja2. Сторонние пакеты могут предоставлять свои бэкенды.</p>
9
<p>Чтобы бэкенд мог что-то сделать с шаблоном, нужно этот шаблон где-то взять. Django самостоятельно загружает шаблоны из файлов, знает, где эти файлы найти, и запоминает/кэширует часто используемые шаблоны в памяти. Нам остается только помнить имя шаблона, который хотим использовать в данный момент.</p>
9
<p>Чтобы бэкенд мог что-то сделать с шаблоном, нужно этот шаблон где-то взять. Django самостоятельно загружает шаблоны из файлов, знает, где эти файлы найти, и запоминает/кэширует часто используемые шаблоны в памяти. Нам остается только помнить имя шаблона, который хотим использовать в данный момент.</p>
10
<p>Настраивается это в settings.py с помощью переменной TEMPLATES. Выглядит настройка так:</p>
10
<p>Настраивается это в settings.py с помощью переменной TEMPLATES. Выглядит настройка так:</p>
11
<ul><li>DIRS - параметр, который перечисляет директории, где будет производиться поиск шаблонов</li>
11
<ul><li>DIRS - параметр, который перечисляет директории, где будет производиться поиск шаблонов</li>
12
<li>APP_DIRS - параметр, который разрешает Django искать шаблоны в директориях приложений</li>
12
<li>APP_DIRS - параметр, который разрешает Django искать шаблоны в директориях приложений</li>
13
</ul><p>Когда APP_DIRS включен, в каждом подключенном приложении будут по умолчанию искаться директории<em>templates</em>, а в них - шаблоны.</p>
13
</ul><p>Когда APP_DIRS включен, в каждом подключенном приложении будут по умолчанию искаться директории<em>templates</em>, а в них - шаблоны.</p>
14
<p>По умолчанию в качестве директории с шаблонами принято указывать<em>templates</em>:</p>
14
<p>По умолчанию в качестве директории с шаблонами принято указывать<em>templates</em>:</p>
15
<h2>Шаблоны приложений</h2>
15
<h2>Шаблоны приложений</h2>
16
<p>У одного приложения в нашем учебном проекте уже есть шаблон. Речь идет о главном приложении hexlet_django_blog и шаблоне hexlet_django_blog/templates/index.html. Django находит и загружает этот шаблон, потому что опция APP_DIRS включена по умолчанию.</p>
16
<p>У одного приложения в нашем учебном проекте уже есть шаблон. Речь идет о главном приложении hexlet_django_blog и шаблоне hexlet_django_blog/templates/index.html. Django находит и загружает этот шаблон, потому что опция APP_DIRS включена по умолчанию.</p>
17
<p>Если сейчас создать новый шаблон hexlet_django_blog/article/templates/index.html, то при поиске по имени<em>index.html</em>первым будет найден старый шаблон hexlet_django_blog/templates/index.html. Так происходит, потому что приложение hexlet_django_blog находится в списке settings.INSTALLED_APPS выше приложения hexlet_django_blog.article. Если переставить приложения местами, то загрузчик шаблонов учтет изменения.</p>
17
<p>Если сейчас создать новый шаблон hexlet_django_blog/article/templates/index.html, то при поиске по имени<em>index.html</em>первым будет найден старый шаблон hexlet_django_blog/templates/index.html. Так происходит, потому что приложение hexlet_django_blog находится в списке settings.INSTALLED_APPS выше приложения hexlet_django_blog.article. Если переставить приложения местами, то загрузчик шаблонов учтет изменения.</p>
18
<p>С помощью управления порядком подключения приложений можно переопределять шаблоны одних приложений шаблонами из других. Это интересная возможность, но из-за нее же приходится следить за тем, чтобы шаблоны не перепутывались случайно.</p>
18
<p>С помощью управления порядком подключения приложений можно переопределять шаблоны одних приложений шаблонами из других. Это интересная возможность, но из-за нее же приходится следить за тем, чтобы шаблоны не перепутывались случайно.</p>
19
<p>Чтобы не думать слишком много над тем, как не путать шаблоны, стоит придерживаться правила:</p>
19
<p>Чтобы не думать слишком много над тем, как не путать шаблоны, стоит придерживаться правила:</p>
20
<blockquote><p>Все шаблоны проекта, которые используются только в нем, стоит хранить в отдельной директории в корне проекта и держать эту директорию в порядке - использовать поддиректории и хорошие имена. Директорию нужно добавить в settings.TEMPLATES.DIRS.</p>
20
<blockquote><p>Все шаблоны проекта, которые используются только в нем, стоит хранить в отдельной директории в корне проекта и держать эту директорию в порядке - использовать поддиректории и хорошие имена. Директорию нужно добавить в settings.TEMPLATES.DIRS.</p>
21
</blockquote><p>Для тех же приложений, которые планируется использовать повторно, внутри соответствующей директории templates нужно иметь поддиректорию с именем приложения и все шаблоны располагать в ней. Это уменьшит вероятность конфликтов имен шаблонов.</p>
21
</blockquote><p>Для тех же приложений, которые планируется использовать повторно, внутри соответствующей директории templates нужно иметь поддиректорию с именем приложения и все шаблоны располагать в ней. Это уменьшит вероятность конфликтов имен шаблонов.</p>
22
<h3>Контекст шаблонизации</h3>
22
<h3>Контекст шаблонизации</h3>
23
<p>Шаблоны превращаются в текст с помощью выполнения кода на языке шаблонизатора. Этот код обычно подразумевает использование каких-то данных, получаемых вне шаблона. Данные передаются в шаблон с помощью контекста, который представляет собой словарь. Когда мы вызываем render(request, 'template.html', context={}), мы передаем этот самый словарь в качестве аргумента.</p>
23
<p>Шаблоны превращаются в текст с помощью выполнения кода на языке шаблонизатора. Этот код обычно подразумевает использование каких-то данных, получаемых вне шаблона. Данные передаются в шаблон с помощью контекста, который представляет собой словарь. Когда мы вызываем render(request, 'template.html', context={}), мы передаем этот самый словарь в качестве аргумента.</p>
24
<p>Часто возникает задача иметь в контексте шаблона доступ к параметрам запроса или настройкам проекта. Передавать такие вещи явно слишком утомительно, поэтому у Django есть механизм Context Processors - посредники между нами и шаблоном, которые расширяют контекст единым образом для всех шаблонов.</p>
24
<p>Часто возникает задача иметь в контексте шаблона доступ к параметрам запроса или настройкам проекта. Передавать такие вещи явно слишком утомительно, поэтому у Django есть механизм Context Processors - посредники между нами и шаблоном, которые расширяют контекст единым образом для всех шаблонов.</p>
25
<p>Процессоры контекста вызываются как функции, которые получают в качестве аргумента request и возвращают словарь. Затем этот словарь дополняет предоставленный нами контекст. Подключаются context processors в settings.TEMPLATES.OPTIONS.context_processors - это список строк с полными именами процессоров.</p>
25
<p>Процессоры контекста вызываются как функции, которые получают в качестве аргумента request и возвращают словарь. Затем этот словарь дополняет предоставленный нами контекст. Подключаются context processors в settings.TEMPLATES.OPTIONS.context_processors - это список строк с полными именами процессоров.</p>
26
<p>С Django поставляется много готовых процессоров контекста. Вот два примера:</p>
26
<p>С Django поставляется много готовых процессоров контекста. Вот два примера:</p>
27
<ul><li>django.template.context_processors.request добавляет в контекст переменную request с очевидным значением</li>
27
<ul><li>django.template.context_processors.request добавляет в контекст переменную request с очевидным значением</li>
28
<li>django.template.context_processors.debug добавляет переменную debug, которая истинна, если сервер запущен в режиме разработчика. С помощью этой переменной можно выводить какую-то отладочную информацию, которая не будет видна в боевом режиме</li>
28
<li>django.template.context_processors.debug добавляет переменную debug, которая истинна, если сервер запущен в режиме разработчика. С помощью этой переменной можно выводить какую-то отладочную информацию, которая не будет видна в боевом режиме</li>
29
</ul><p>В дополнение к встроенным можно создавать и свои процессоры контекста или же брать их из сторонних библиотек.</p>
29
</ul><p>В дополнение к встроенным можно создавать и свои процессоры контекста или же брать их из сторонних библиотек.</p>
30
<h2>Работа с шаблонизатором Django</h2>
30
<h2>Работа с шаблонизатором Django</h2>
31
<p>Пример простого Django-шаблона:</p>
31
<p>Пример простого Django-шаблона:</p>
32
<p>Шаблон выглядит как HTML, но со вставками кода. Во многом встроенный Django шаблонизатор схож с шаблонизатором Jinja2 - подстановка любого значения выполняется в двойных фигурных скобках {{ ... }}. Это очень похоже на интерполяцию, если сам шаблон рассматривать как строку.</p>
32
<p>Шаблон выглядит как HTML, но со вставками кода. Во многом встроенный Django шаблонизатор схож с шаблонизатором Jinja2 - подстановка любого значения выполняется в двойных фигурных скобках {{ ... }}. Это очень похоже на интерполяцию, если сам шаблон рассматривать как строку.</p>
33
<p>Под капотом Django выполняет дополнительную обработку и экранирует любые данные, которые вставлены таким образом. Это значит, что нам не нужно прилагать дополнительные усилия, чтобы обеспечить безопасность в шаблонах.</p>
33
<p>Под капотом Django выполняет дополнительную обработку и экранирует любые данные, которые вставлены таким образом. Это значит, что нам не нужно прилагать дополнительные усилия, чтобы обеспечить безопасность в шаблонах.</p>
34
<p>Данные в шаблон поступают из вью в виде контекста:</p>
34
<p>Данные в шаблон поступают из вью в виде контекста:</p>
35
<p>Двойные фигурные скобки позволяют не только выводить информацию, которую передали в контексте, но и производить ее простую обработку при помощи встроенных<a>тегов и фильтров</a>шаблонов. Главное правило - не злоупотреблять. В основном данные должны быть подготовлены в обработчике до того, как они попадут в шаблон. Тут нужно помнить: шаблоны - про отображение, а не про логику работы.</p>
35
<p>Двойные фигурные скобки позволяют не только выводить информацию, которую передали в контексте, но и производить ее простую обработку при помощи встроенных<a>тегов и фильтров</a>шаблонов. Главное правило - не злоупотреблять. В основном данные должны быть подготовлены в обработчике до того, как они попадут в шаблон. Тут нужно помнить: шаблоны - про отображение, а не про логику работы.</p>
36
<p>Кроме подстановки во встроенном шаблонизаторе есть инструкции. С их помощью реализованы все управляющие конструкции, например, циклы, условия и многое другое:</p>
36
<p>Кроме подстановки во встроенном шаблонизаторе есть инструкции. С их помощью реализованы все управляющие конструкции, например, циклы, условия и многое другое:</p>
37
<p>Инструкции всегда оборачиваются в фигурные скобки со знаком процента {% ... %} и часто имеют закрывающую часть. При помощи инструкций можно делать практически то же самое, что и в самом Python. В инструкциях, как и в подстановках, можно использовать переменные из контекста.</p>
37
<p>Инструкции всегда оборачиваются в фигурные скобки со знаком процента {% ... %} и часто имеют закрывающую часть. При помощи инструкций можно делать практически то же самое, что и в самом Python. В инструкциях, как и в подстановках, можно использовать переменные из контекста.</p>
38
<p>Простые конструкции вроде обращения по ключу, по индексу, по имени атрибута нам доступны. Поэтому контекст может содержать и сложносоставные сущности. А вот вызывать функции и методы уже не получится - это то самое отделение логики от представления.</p>
38
<p>Простые конструкции вроде обращения по ключу, по индексу, по имени атрибута нам доступны. Поэтому контекст может содержать и сложносоставные сущности. А вот вызывать функции и методы уже не получится - это то самое отделение логики от представления.</p>