Шаблоны Django

Вы получили нужные записи из базы данных и вывели их на главную страницу сайта. С технической стороны всё хорошо, но страница выглядит ужасно. Пора подключить HTML-шаблоны — вы знакомились с ними на бесплатном курсе по Django.
Шаблон документа создаётся заранее, это как красивая пустая коробка, обложка без содержимого. В него (например, при вызове функции render()) передаются конкретные данные, после чего сформированный HTML-документ отправляется пользователю. Данные в шаблон функция render() передаёт словарём (dict), обычно этот словарь называют context. Значениями элементов этого словаря могут быть любые данные.

Рендеринг шаблона

Страница, созданная на основе шаблонов, должна быть отдана пользователю. Для этого должен пройти специальный процесс, rendering (англ. «отрисовка»).
Рендеринг — это превращение исходного кода в результат, который видит пользователь. Например, 3D-мультипликаторы в программах трехмерной графики создают персонажей и эффекты, а потом, после рендеринга исходных файлов, получается видео.
Нам надо из исходников-шаблонов создать для пользователя HTML-документ. Для этого в шаблон «вписываются» переменные, а сама страница может «монтироваться» из нескольких шаблонов.
Результат выполнения функции render() — это объект класса HttpResponse, объект ответа. В нём хранится HTML-код возвращаемой страницы.
Скопировать кодPYTHON
from django.shortcuts import render def my_index(request): # какой-то код return render( request, # первый параметр — это всегда request 'index.html', # имя шаблона, который нужен для отображения страницы {'title': 'Этот текст встанет в шаблон на место переменной "title"'} # словарь содержит переменные, которые будут переданы в шаблон )

Переменные

В шаблонах Django есть собственный синтаксис для работы с переменными. При выводе значения переменной её имя указывают в двойных фигурных скобках:
Скопировать кодHTML
{{ variable }}
Если при вызове шаблона передать в него переменную по имени variable, то вместо конструкции с двойными фигурными скобками будет выведено значение переменной. Вывести переменные в HTML-теги можно так:
Скопировать кодHTML
<h1> {{ title }} </h1> <p> {{ body }} </p>
К элементу словаря, свойству объекта или элементу списка можно обратиться через точечную нотацию:
Скопировать кодHTML
{{ var_dict.key }} — обращение к ключу словаря {{ var_instance.attribute }} — обращение к свойству или методу класса {{ var_list.0 }} — обращение к элементу списка
Процессор шаблонов упрощает обращение к свойствам и ключам объектов. Вам многократно придется пользоваться нотацией через точку. Например если объект user содержит свойство username, то код в шаблоне будет очень похожим на обращение к объекту в Python: {{ user.username }}. Если же объект user — это словарь, в котором есть ключ username, то в шаблоне все равно надо писать {{ user.username }}. Это упрощает работу с переменными, но делает невозможным сложные конструкции, требующие вычислений.
Если у объекта есть метод, то обращаются к нему так же, как к свойству. Обработчик шаблона сам определит, что надо вызвать метод — и опубликует результат вызова. В целях безопасности в шаблонах заблокирована возможность передавать методам параметры.

Теги

Для более сложных конструкций, влияющих на логику исполнения кода, существуют элементы разметки, теги. Это не HTML-теги, а совершенно другая сущность. В коде теги шаблонов выделяются конструкциями {% и %}.
Тег ветвления {% if %} очень похож на оператор if/elif/else в языке Python. Обратите внимание: у тега if есть обязательный закрывающий тег endif:
Скопировать кодHTML
{% if user.is_authenticated %} Привет, {{ user.username }}. {% else %} Будет здорово, если вы авторизуетесь! {% endif %}
Теги могут получать параметры:
Скопировать кодHTML
{% include "counter.html" %}
На место этого тега в шаблон будет встроено содержимое файла counter.html.
В Django есть много встроенных тегов, но их можно создать и самостоятельно, мы это сделаем при разработке проекта Yatube.

Фильтры

Фильтры нужны для обработки значений переменных или аргументов других тегов. В коде шаблона фильтры присоединяются к фильтруемому значению через символ |:
имя_переменной | фильтр
В Django есть множество встроенных фильтров. Например, фильтр length вернёт длину строки или последовательности, переданной в переменной variable:
Скопировать кодHTML
{{ variable | length }}
Если в переменную variable передать слово «гиппопотомомонстросесквиппедалиофобия», то в шаблон будет выведено число 37, по числу букв в слове.
В бесплатном курсе по Django вы встретились с конструкцией {{ variable | safe }} и потестировали её.
Если в шаблоне просто {{ variable }}:
image
Если в шаблоне variable | safe :
image
Фильтры можно объединять в цепочку:
Скопировать кодHTML
{{ variable | title | truncatewords:4 }}
Если переменная variable содержит строку ЭТО ОДиН маЛЕНЬкий шаг для чеЛОВека и оГрОмНыЙ СКачОК для челоВЕЧЕсТВА, то сначала фильтр title преобразует регистр букв в формат «каждое слово с заглавной» Это Один Маленький Шаг Для Человека И Огромный Скачок Для Человечества, а потом truncate обрежет текст до четырёх первых слов. В результате на страницу будет выведено Это Один Маленький Шаг.
Фильтр date работает только с объектами типа date и datetime: он форматирует дату по маске. За основу взят стандарт, принятый в языке программирования PHP.
Если вывести дату без форматирования, то получится что-то вроде '2019-02-02 00:00:00+00:00'. Это не лучший вариант. Фильтр date позволяет вывести дату в любой форме:
Скопировать кодHTML
{{ pub_date|date:"j.m.Y" }} {# выведет 2.02.2019 #} {{ pub_date|date:"j F Y" }} {# выведет 2 февраля 2019 #} {{ pub_date|date:"d.m.y" }} {# выведет 02.02.19 #} {{ pub_date|date:"d M Y" }} {# выведет 02 фев 2019 #}
При выводе текстов тоже есть особенности. Пользователю удобно обозначать начало нового абзаца переводом строки, но HTML не понимает такого форматирования и выведет текст сплошным потоком, без разрывов. В Django Templates есть фильтр linebreaksbr. Он заменяет символы перевода строки \n на HTML-теги <br>.

Комментарии

Django-шаблоны поддерживают комментарии — строки, которые игнорируются при интерпретации кода. Однострочные комментарии записываются между символами {# и #}, многострочные — между конструкциями {% comment %} и {% endcomment %}.
Скопировать кодHTML
{% comment "Опциональный текст, комментарий к комментарию" %} <p>Этот кусок шаблона временно отключен {{ create_date|date:"c" }}</p> {% endcomment %}