Основа для создания динамических HTML-страниц. Сочетают статический HTML с переменными и управляющей логикой Django Template Language (DTL).
- Директории:
- Рекомендуется создавать подкаталог с именем приложения внутри
templates/
(templates/<app_name>/
), чтобы избежать конфликтов имен шаблонов между приложениями. Путь к шаблону тогда будет<app_name>/template.html
.
- Рекомендуется создавать подкаталог с именем приложения внутри
- Переменные:
- Вставляются с помощью
{{ variable_name }}
. - Доступ к атрибутам объекта:
{{ object.attribute }}
. - Доступ к элементам словаря:
{{ dictionary.key }}
. - Доступ к элементам списка по индексу:
{{ list.0 }}
. - Вызов методов объекта (без аргументов):
{{ object.method }}
. - Нельзя:
{{ title, name }}
- Вставляются с помощью
- Алгоритм поиска шаблонов:
- Сначала поиск в каталогах, указанных в списке
DIRS
в настройкеTEMPLATES
(settings.py
). - Если не найден и
APP_DIRS
установлено вTrue
, поиск в подкаталогахtemplates
каждого приложения, перечисленного вINSTALLED_APPS
. - Используется первый найденный шаблон.
- Если шаблон не найден нигде, возбуждается исключение
TemplateDoesNotExist
. - Кэширование: Django кэширует скомпилированные шаблоны для производительности (в режиме
DEBUG=False
). - Настройка: Можно переопределить поиск с помощью
django.template.loader.get_template()
.
- Сначала поиск в каталогах, указанных в списке
- Фильтры: Применяются к переменным для их модификации.
- Синтаксис:
{{ variable|filter_name:"argument" }}
- Примеры:
add
:{{ value|add:"2" }}
(пытается сложить, может работать со строками/числами)capfirst
:{{ my_string|capfirst }}
(Первая буква заглавная)upper
:{{ my_string|upper }}
(ВСЕ БУКВЫ ЗАГЛАВНЫЕ)lower
:{{ my_string|lower }}
(все буквы строчные)cut
:{{ my_string|cut:" " }}
(Удаляет все пробелы)default
:{{ value|default:"Нет значения" }}
(Еслиvalue
ложно (пусто,None
,False
,0
))divisibleby
:{{ number|divisibleby:"3" }}
(ВозвращаетTrue
, еслиnumber
делится на 3)first
:{{ my_list|first }}
(Первый элемент списка/строки)last
:{{ my_list|last }}
(Последний элемент)join
:{{ my_list|join:", " }}
(Объединяет элементы списка в строку с разделителем)length
:{{ my_list|length }}
(Длина списка/строки)slugify
:{{ my_string|slugify }}
(“Some Title” → “some-title”)
- Использование в Python (Не рекомендуется):
from django.template.defaultfilters import slugify slug = slugify(my_string)
- Создание пользовательских фильтров:
- В каталоге приложения создать папку
templatetags
(на одном уровне сmodels.py
,views.py
). - Внутри
templatetags
создать файл__init__.py
(пустой). - Внутри
templatetags
создать Python-файл для фильтров (например,custom_filters.py
). - Определить и зарегистрировать фильтры в этом файле:
# myapp/templatetags/custom_filters.py from django import template register = template.Library() # Экземпляр для регистрации @register.filter(name='multiply') # Регистрация с явным именем def multiply_filter(value, arg): try: return value * arg except (ValueError, TypeError): return '' @register.filter # Регистрация (имя = имя функции) def first_letters(value, count=1): try: return value[:int(count)] except (ValueError, TypeError, IndexError): return ''
- Использовать в шаблонах после загрузки:
{% load custom_filters %} {{ some_number|multiply:5 }} {{ some_string|first_letters:"3" }} ```* **Теги:** Управляющие конструкции шаблона.
- В каталоге приложения создать папку
- Синтаксис:
{% tag_name arguments %}
{% for ... %}
: Цикл по итерируемому объекту.<ul> {% for item in item_list %} <li>{{ forloop.counter }}. {{ item.name }}</li> {% empty %} <li>Список пуст.</li> {% endfor %} </ul>
- Переменные внутри цикла (
forloop
):forloop.counter
(1..N),forloop.counter0
(0..N-1),forloop.revcounter
(N..1),forloop.revcounter0
(N-1..0),forloop.first
(True для первой итерации),forloop.last
(True для последней),forloop.parentloop
(доступ кforloop
внешнего цикла во вложенных циклах).
- Переменные внутри цикла (
{% if ... %}
: Условный оператор.{% if user.is_authenticated %} Привет, {{ user.username }}! {% elif user.is_staff %} Вход для персонала. {% else %} <a href="{% url 'login' %}">Войти</a> {% endif %}
{% url ... %}
: Генерация URL по имени изurls.py
. Аналогreverse()
для шаблонов.<!-- Синтаксис --> {% url 'url-name' positional_arg1 positional_arg2 %} {% url 'url-name' keyword_arg1=value1 keyword_arg2=value2 %} <!-- Пример 1: Без аргументов --> <a href="{% url 'home' %}">Домашняя страница</a> <!-- Пример 2: С аргументом --> <a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a> <!-- Пример 3: В цикле --> <ul> <li><a href="{% url 'home' %}">Главная</a></li> {% for m in menu %} <li><a href="{% url m.url_name %}">{{ m.title }}</a></li> {% endfor %} </ul>
- Теги наследования:
{% block <имя_блока> %}
: Определяет именованный блок в родительском шаблоне, который может быть переопределен в дочернем.<!-- base.html --> <!DOCTYPE html> <html> <head> <title>{% block title %}Стандартный заголовок{% endblock %}</title> </head> <body> <main> {% block content %}{% endblock %} </main> </body> </html>
{% extends "имя_родительского_шаблона.html" %}
: Указывает, что текущий шаблон наследует от родительского. Должен быть первым тегом в файле. Дочерний шаблон переопределяет блоки из родительского.<!-- child.html --> {% extends "base.html" %} {% block title %}Моя страница{% endblock %} {% block content %} <h1>Содержимое моей страницы</h1> {% endblock %}
{{ block.super }}
: Используется внутри{% block %}
в дочернем шаблоне для вставки оригинального содержимого этого блока из родительского шаблона.{% block content %} {{ block.super }} <!-- Вставит контент из base.html --> <p>Дополнительный контент.</p> {% endblock %}
{% include "имя_шаблона.html" %}
: Включает содержимое другого шаблона в текущий. Удобно для переиспользуемых частей (шапка, подвал).{% include "includes/header.html" %} <!-- Передача переменных во включаемый шаблон --> {% include "includes/user_card.html" with user=request.user profile=user_profile %} <!-- Изоляция контекста (переменные текущего шаблона не передаются) --> {% include "includes/footer.html" only %}
{% load ... %}
: Загружает пользовательские теги или фильтры, либо встроенные библиотеки (например,static
).{% load static %} {% load custom_tags_library %}
{% static "путь/к/файлу" %}
: Генерирует URL для статического файла (CSS, JS, изображения). Требует{% load static %}
.<link rel="stylesheet" href="{% static 'css/styles.css' %}"> <img src="{% static 'images/logo.png' %}" alt="Логотип">
- Создание пользовательских тегов: Похоже на создание фильтров, но используются декораторы
@register.simple_tag
и@register.inclusion_tag
.simple_tag
: Принимает аргументы, обрабатывает их и возвращает строку (или записывает в контекст черезas
).# myapp/templatetags/custom_tags.py # ... (register = template.Library()) ... @register.simple_tag(takes_context=True) # takes_context=True для доступа к контексту def show_greeting(context, user_name): request = context['request'] # Пример доступа к request return f"Hello, {user_name}! Welcome to {request.get_host()}" @register.simple_tag def get_latest_posts(count=5): # ... логика получения постов ... return Post.objects.order_by('-created_at')[:count]
{% load custom_tags %} {% show_greeting user.username %} {% get_latest_posts 3 as latest_posts %} <ul> {% for post in latest_posts %}<li>{{ post.title }}</li>{% endfor %} </ul>
inclusion_tag
: Рендерит другой шаблон с переданным ему контекстом и вставляет результат.# myapp/templatetags/custom_tags.py # ... (register = template.Library()) ... @register.inclusion_tag('myapp/includes/category_menu.html') def render_category_menu(active_category=None): categories = Category.objects.all() return {'categories': categories, 'active_category': active_category}
<!-- myapp/includes/category_menu.html --> <ul> {% for category in categories %} <li class{% if category == active_category %}="active"{% endif %}> <a href="{{ category.get_absolute_url }}">{{ category.name }}</a> </li> {% endfor %} </ul>
<!-- Основной шаблон --> {% load custom_tags %} <nav>{% render_category_menu current_category %}</nav>
- Синтаксис:
- Статические файлы:
- CSS, JavaScript, изображения, шрифты и т.д.
- Хранение:
- В каталоге
static/
внутри каждого приложения (DEBUG=True
). - В каталогах, указанных в
STATICFILES_DIRS
вsettings.py
(DEBUG=True
). - В одном общем каталоге
STATIC_ROOT
(дляDEBUG=False
, продакшен). Командаpython manage.py collectstatic
собирает все статические файлы из приложений иSTATICFILES_DIRS
вSTATIC_ROOT
.
- В каталоге
- Настройка (
settings.py
):STATIC_URL
: URL-префикс для статических файлов (например,/static/
).STATICFILES_DIRS
: Список путей для поиска статики вне приложений.STATIC_ROOT
: Путь к каталогу дляcollectstatic
.
- Использование в шаблонах: Через тег
{% static %}
(требует{% load static %}
).
〰〰〰 𓆝 𓆟 𓆞 𓆝 𓆟 𓆝 𓆟 𓆞 〰〰〰