Topic 3 of 6

Course materials are currently available in Russian only.

Шаблоны 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.