Основа для создания динамических 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 %}).
〰〰〰 𓆝 𓆟 𓆞 𓆝 𓆟 𓆝 𓆟 𓆞 〰〰〰