Шаблоны Django
Как и во Flask, HTML в Django собирают шаблонами. Язык шаблонов Django похож на Jinja, но проще: в нём нарочно нельзя писать произвольный Python — логика остаётся в представлениях.
Шаблон и контекст
Обычно шаблоны лежат в папке templates, а представление рисует их функцией render:
from django.shortcuts import render
def feed(request):
return render(request, "feed.html", {"posts": POSTS})
В задачах шаблон хранится в строке:
from django.template import Template, Context
html = Template("<h1>{{ title }}</h1>").render(Context({"title": "Мой блог"}))
Для этого в настройках должен быть указан движок: TEMPLATES=[{"BACKEND": "django.template.backends.django.DjangoTemplates"}].
Переменные, циклы, условия
{% for post in posts %}
<h2>{{ forloop.counter }}. {{ post.title }}</h2>
{% empty %}
<p>Постов пока нет</p>
{% endfor %}
{% if user.is_authenticated %}Привет, {{ user.username }}!{% endif %}
{{ … }}— значение; точка достаёт поле словаря, атрибут или элемент списка (post.title,items.0);- внутри цикла —
forloop.counter(с единицы),forloop.first,forloop.last; {% empty %}— что вывести, если список пуст;- всё выводимое экранируется:
<script>станет текстом.
Фильтры
{{ post.text|truncatewords:30 }} первые 30 слов и «…»
{{ post.title|upper }}
{{ posts|length }}
{{ post.tags|join:", " }}
{{ post.subtitle|default:"—" }} если значение пустое
{{ post.created|date:"d.m.Y" }} 05.10.2026
{{ post.text|linebreaksbr }} переводы строк → <br>
Аргумент фильтра пишется через двоеточие. Фильтры соединяются в цепочку слева направо: {{ tags|join:", "|default:"без тегов" }} — сначала склеить, а если получилась пустая строка — подставить запасной текст.
Коды формата даты: d — день с нулём, j — без нуля, m — месяц с нулём, Y — год четырьмя цифрами, y — двумя, H:i — часы и минуты.
Свои фильтры
from django import template
register = template.Library()
@register.filter
def ru_plural(n, forms):
one, few, many = forms.split(",")
...
Фильтр — функция от значения и (необязательно) аргумента. В проекте её кладут в templatetags/ приложения и подключают в шаблоне через {% load %}; в одном файле — через настройку "OPTIONS": {"builtins": [...]}.
Пример — русские окончания. Встроенный pluralize умеет только добавлять окончание, как в английском (post/posts), а у нас три формы: 1 комментарий, 2 комментария, 5 комментариев. Смотрят на последние две цифры: 11–14 — всегда третья форма.
Итог
Template(...).render(Context({...}))илиrender(request, "файл.html", {...});{% for %} … {% empty %} … {% endfor %},forloop.counter;- фильтры
truncatewords,length,join,default,date; цепочки; - свой фильтр —
template.Library()и@register.filter.