HTML Diff
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>