Spec-Zone.ru › Django 5.1

Шаблоны

В качестве веб-фреймворка Django нуждается в удобном способе динамического генерирования HTML. Наиболее распространённый подход основан на шаблонах. Шаблон содержит статические части желаемого HTML-вывода, а также специальный синтаксис, описывающий, как будет вставлено динамическое содержимое. Для практического примера создания HTML-страниц с помощью шаблонов см. Учебник 3.

Проект Django может быть настроен с одним или несколькими движками шаблонов (или даже с нулём, если вы не используете шаблоны). Django поставляется со встроенными бэкендами для собственной системы шаблонов, креативно названной языком шаблонов Django (DTL), и для популярной альтернативы Jinja2. Бэкэнды для других языков шаблонов могут быть доступны от сторонних разработчиков. Вы также можете написать свой собственный пользовательский бэкенд, см. Пользовательский бэкенд шаблонов

Django определяет стандартный API для загрузки и рендеринга шаблонов независимо от бэкенда. Загрузка включает в себя поиск шаблона для данного идентификатора и его предварительную обработку, обычно компиляцию в представление в оперативной памяти. Рендеринг означает интерполяцию шаблона с данными контекста и возвращение результирующей строки.

Язык шаблонов Django — собственная система шаблонов Django. До версии Django 1.8 это был единственный встроенный вариант. Это хорошая библиотека шаблонов, хотя она довольно категорична и имеет несколько особенностей. Если у вас нет веской причины выбрать другой бэкенд, вы должны использовать DTL, особенно если вы пишете подключаемый модуль, и планируете распространять шаблоны. Приложения contrib Django, которые включают шаблоны, такие как django.contrib.admin, используют DTL.

По историческим причинам как общая поддержка движков шаблонов, так и реализация языка шаблонов Django находятся в пространстве имён django.template.

Предупреждение

Система шаблонов не защищена от небезопасных авторов шаблонов. Например, сайт не должен разрешать своим пользователям предоставлять собственные шаблоны, поскольку авторы шаблонов могут выполнять такие действия, как XSS-атаки и доступ к свойствам переменных шаблонов, которые могут содержать конфиденциальную информацию.

Введение в язык шаблонов Django

Синтаксис

О данной секции

Это обзор синтаксиса языка шаблонов Django. Подробности см. в справочнике по синтаксису языка.

Шаблон Django — это текстовый документ или строка Python, помеченная с помощью языка шаблонов Django. Некоторые конструкции распознаются и интерпретируются движком шаблонов. Основные из них — переменные и теги.

Шаблон рендерится с контекстом. Рендеринг заменяет переменные их значениями, которые ищутся в контексте, и выполняет теги. Всё остальное выводится как есть.

Синтаксис языка шаблонов Django включает четыре конструкции.

Переменные

Переменная выводит значение из контекста, который представляет собой объект, подобный словарю, сопоставляющий ключи со значениями.

Переменные заключены в {{ и }}, как в этом примере:

My first name is {{ first_name }}. My last name is {{ last_name }}.

С контекстом {'first_name': 'John', 'last_name': 'Doe'}, этот шаблон отображается так:

My first name is John. My last name is Doe.

Поиск по словарю, поиск по атрибутам и поиск по индексам списков реализованы с использованием нотации точек:

{{ my_dict.key }}
{{ my_object.attribute }}
{{ my_list.0 }}

Если переменная разрешается в вызываемый объект, система шаблонов вызовет его без аргументов и воспользуется его результатом вместо вызываемого объекта.

Теги

Теги обеспечивают произвольную логику в процессе рендеринга.

Это определение преднамеренно расплывчато. Например, тег может выводить содержимое, служить структурой управления (например, оператором «if» или циклом «for»), извлекать содержимое из базы данных или даже предоставлять доступ к другим тегам шаблонов.

Теги заключены в {% и %}, как в этом примере:

{% csrf_token %}

Большинство тегов принимают аргументы:

{% cycle 'odd' 'even' %}

Некоторые теги требуют начального и конечного тега:

{% if user.is_authenticated %}Hello, {{ user.username }}.{% endif %}

Также доступен справочник встроенных тегов, а также инструкции по написанию пользовательских тегов.

Фильтры

Фильтры преобразуют значения переменных и аргументов тегов.

Они выглядят так:

{{ django|title }}

С контекстом {'django': 'the web framework for perfectionists with deadlines'}, этот шаблон отображается так:

The Web Framework For Perfectionists With Deadlines

Некоторые фильтры принимают аргумент:

{{ my_date|date:"Y-m-d" }}

Также доступен справочник встроенных фильтров, а также инструкции по написанию пользовательских фильтров.

Комментарии

Комментарии выглядят так:

{# this won't be rendered #}

Тег {% comment %} предоставляет многострочные комментарии.

Компоненты

О данной секции

Это обзор API языка шаблонов Django. Подробности см. в справочнике по API.

Движок

django.template.Engine инкапсулирует экземпляр системы шаблонов Django. Основная причина прямого создания экземпляра Engine заключается в использовании языка шаблонов Django вне проекта Django.

django.template.backends.django.DjangoTemplates — это тонкий обертка, адаптирующая django.template.Engine к API бэкенда шаблонов Django.

Шаблон

django.template.Template представляет собой скомпилированный шаблон. Шаблоны получают с помощью Engine.get_template() или Engine.from_string().

Аналогично, django.template.backends.django.Template — это тонкий обертка, адаптирующая django.template.Template к общему API шаблонов.

Контекст

django.template.Context хранит метаданные в дополнение к данным контекста. Он передаётся в Template.render() для рендеринга шаблона.

django.template.RequestContext — это подкласс Context, который хранит текущий HttpRequest и выполняет обработчики контекста шаблонов.

В общем API нет эквивалентной концепции. Данные контекста передаются в обычном dict, а текущий HttpRequest передаётся отдельно, если это необходимо.

Загрузчики

Загрузчики шаблонов отвечают за поиск шаблонов, их загрузку и возвращение объектов Template.

Django предоставляет несколько встроенных загрузчиков шаблонов и поддерживает пользовательские загрузчики шаблонов.

Обработчики контекста

Обработчики контекста — это функции, которые получают текущий HttpRequest в качестве аргумента и возвращают dict данных, которые будут добавлены в контекст рендеринга.

Их основное применение — добавление общих данных, используемых всеми шаблонами, в контекст, без повторения кода в каждом представлении.

Django предоставляет много встроенных обработчиков контекста, и вы также можете реализовать собственные дополнительные обработчики контекста.

Поддержка движков шаблонов

Настройка

Движки шаблонов настраиваются с помощью параметра TEMPLATES. Это список конфигураций, по одной для каждого движка. Значение по умолчанию — пустое. Значение, сгенерированное командой startproject, имеет более полезное значение:

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            # ... some options here ...
        },
    },
]

BACKEND — это пунктирный путь Python к классу движка шаблонов, реализующему API бэкенда шаблонов Django. Встроенные бэкэнды — django.template.backends.django.DjangoTemplates и django.template.backends.jinja2.Jinja2.

Поскольку большинство движков загружают шаблоны из файлов, в верхнем уровне конфигурации каждого движка содержатся две общие настройки:

  • DIRS определяет список каталогов, где движок должен искать исходные файлы шаблонов в порядке поиска.
  • APP_DIRS указывает, должен ли движок искать шаблоны внутри установленных приложений. Каждый бэкенд определяет условное имя подкаталога внутри приложений, где должны храниться его шаблоны.

Хотя это нечасто встречается, можно настроить несколько экземпляров одного и того же бэкенда с разными параметрами. В этом случае для каждого движка следует определить уникальное NAME.

OPTIONS содержит настройки, специфичные для бэкенда.

Использование

Модуль django.template.loader определяет две функции для загрузки шаблонов.

get_template(template_name, using=None) [source]

Эта функция загружает шаблон с заданным именем и возвращает объект Template.

Точный тип возвращаемого значения зависит от бэкенда, который загрузил шаблон. У каждого бэкенда есть свой собственный класс Template.

get_template() перебирает каждый движок шаблонов в порядке следования до тех пор, пока один из них не будет успешен. Если шаблон не найден, генерируется исключение TemplateDoesNotExist. Если шаблон найден, но содержит неверный синтаксис, генерируется исключение TemplateSyntaxError.

Как шаблоны ищутся и загружаются, зависит от бэкенда каждого движка и его конфигурации.

Если вы хотите ограничить поиск определённым движком шаблонов, передайте имя бэкенда NAME в аргументе using.

select_template(template_name_list, using=None) [source]

select_template() аналогичен get_template(), за исключением того, что он принимает список имён шаблонов. Он перебирает имена в порядке следования и возвращает первый найденный существующий шаблон.

Если загрузка шаблона завершается неудачей, могут быть подняты следующие два исключения, определённые в django.template:

exception TemplateDoesNotExist(msg, tried=None, backend=None, chain=None) [source]

Это исключение генерируется, когда шаблон не найден. Оно принимает следующие необязательные аргументы для заполнения справки по шаблону на странице отладки:

backend
Экземпляр бэкенда шаблонов, из которого произошло исключение.
tried
Список источников, которые были проверены при поиске шаблона. Он представлен в виде списка кортежей, содержащих (origin, status), где origin — объект типа origin-like, а status — строка с причиной отсутствия шаблона.
chain
Список промежуточных исключений TemplateDoesNotExist, которые возникали при попытке загрузить шаблон. Это используется функциями, например get_template(), которые пытаются загрузить заданный шаблон из нескольких движков.
exception TemplateSyntaxError(msg) [source]

Это исключение генерируется, когда шаблон был найден, но содержит ошибки.

Объекты Template, возвращаемые функциями get_template() и select_template(), должны предоставлять метод render() со следующим сигнатуром:

Template.render(context=None, request=None)

Отображает этот шаблон с заданным контекстом.

Если context указан, он должен быть словарём. Если он не указан, движок отобразит шаблон с пустым контекстом.

Если request указан, он должен быть объектом запроса. Тогда движок должен сделать его, а также маркер CSRF, доступными в шаблоне. Как это достигается, зависит от каждого бэкенда.

Вот пример алгоритма поиска. Для этого примера настройка TEMPLATES имеет вид:

TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            "/home/html/example.com",
            "/home/html/default",
        ],
    },
    {
        "BACKEND": "django.template.backends.jinja2.Jinja2",
        "DIRS": [
            "/home/html/jinja2",
        ],
    },
]

Если вы вызовете get_template('story_detail.html'), Django будет искать следующие файлы в указанном порядке:

  • /home/html/example.com/story_detail.html ('django' движок)
  • /home/html/default/story_detail.html ('django' движок)
  • /home/html/jinja2/story_detail.html ('jinja2' движок)

Если вы вызовете select_template(['story_253_detail.html', 'story_detail.html']), Django будет искать следующие файлы:

  • /home/html/example.com/story_253_detail.html ('django' движок)
  • /home/html/default/story_253_detail.html ('django' движок)
  • /home/html/jinja2/story_253_detail.html ('jinja2' движок)
  • /home/html/example.com/story_detail.html ('django' движок)
  • /home/html/default/story_detail.html ('django' движок)
  • /home/html/jinja2/story_detail.html ('jinja2' движок)

Когда Django найдёт существующий шаблон, поиск прекратится.

Используйте django.template.loader.select_template() для большей гибкости

Вы можете использовать select_template() для гибкой загрузки шаблонов. Например, если вы написали новостную статью и хотите, чтобы некоторые статьи имели пользовательские шаблоны, используйте что-то вроде select_template(['story_%s_detail.html' % story.id, 'story_detail.html']). Это позволит использовать пользовательский шаблон для отдельной статьи с резервным шаблоном для статей, у которых нет пользовательских шаблонов.

Возможна и предпочтительна организация шаблонов в подкаталогах внутри каждого каталога, содержащего шаблоны. Принято создавать подкаталог для каждого приложения Django, с подкаталогами в этих подкаталогах по мере необходимости.

Сделайте это для собственного удобства. Хранение всех шаблонов в корневом уровне одного каталога становится неразборчивым.

Для загрузки шаблона, находящегося в подкаталоге, используйте косую черту, как в этом примере:

get_template("news/story_detail.html")

Используя тот же параметр TEMPLATES, что и выше, Django будет пытаться загрузить следующие шаблоны:

  • /home/html/example.com/news/story_detail.html ('django' движок)
  • /home/html/default/news/story_detail.html ('django' движок)
  • /home/html/jinja2/news/story_detail.html ('jinja2' движок)

Кроме того, чтобы сократить повторяющиеся действия по загрузке и отображению шаблонов, Django предоставляет функцию-обёртку, которая автоматизирует этот процесс.

render_to_string(template_name, context=None, request=None, using=None) [source]

render_to_string() загружает шаблон, как и get_template(), и сразу же вызывает его метод render(). Она принимает следующие аргументы.

template_name
Имя шаблона для загрузки и отображения. Если это список имён шаблонов, Django использует select_template() вместо get_template() для поиска шаблона.
context
Словарь, который будет использоваться в качестве контекста шаблона для отображения.
request
Необязательный объект запроса, который будет доступен во время отображения шаблона.
using
Необязательное имя NAME движка шаблонов. Поиск шаблона будет ограничен этим движком.

Пример использования:

from django.template.loader import render_to_string

rendered = render_to_string("my_template.html", {"foo": "bar"})

См. также функцию-обёртку render(), которая вызывает render_to_string() и передаёт результат в объект ответа, подходящий для возврата из представления.

Наконец, вы можете использовать настроенные движки напрямую:

engines

Шаблонные движки доступны в django.template.engines:

from django.template import engines

django_engine = engines["django"]
template = django_engine.from_string("Hello {{ name }}!")

Ключ поиска — 'django' в этом примере — это NAME движка.

Встроенные бэкэнды

class DjangoTemplates [source]

Установите BACKEND в 'django.template.backends.django.DjangoTemplates' для настройки движка шаблонов Django.

Когда APP_DIRS равно True, DjangoTemplates движки ищут шаблоны в подкаталоге templates установленных приложений. Это общее имя было сохранено для обратной совместимости.

DjangoTemplates движки принимают следующие OPTIONS:

  • 'autoescape': логическое значение, которое управляет включением/выключением автоматической экранировки HTML.

    По умолчанию True.

    Предупреждение

    Установите его только в False случае рендеринга не-HTML шаблонов!

  • 'context_processors': список точечных путей Python к вызываемым функциям, которые используются для заполнения контекста при рендеринге шаблона с запросом. Эти вызываемые функции принимают объект запроса в качестве аргумента и возвращают dict элементов, которые нужно объединить в контекст.

    По умолчанию пустой список.

    См. RequestContext для получения дополнительной информации.

  • 'debug': логическое значение, включающее/выключающее режим отладки шаблонов. Если он True, то на странице ошибки будет отображаться подробный отчёт об исключении, возникшем во время рендеринга шаблона. Этот отчёт содержит релевантный фрагмент шаблона с выделенной соответствующей строкой.

    По умолчанию значение настройки DEBUG.

  • 'loaders': список точечных путей Python к классам загрузчиков шаблонов. Каждый класс Loader знает, как загрузить шаблоны из определённого источника. Вместо строки можно использовать кортеж. Первый элемент кортежа должен быть именем класса Loader, а последующие элементы передаются классу Loader во время инициализации.

    Значение по умолчанию зависит от значений DIRS и APP_DIRS.

    См. Типы загрузчиков для подробностей.

  • 'string_if_invalid': выход в виде строки, который должна использовать система шаблонов для недопустимых (например, с ошибочными именами) переменных.

    По умолчанию пустая строка.

    См. Обработка недопустимых переменных шаблона для подробностей.

  • 'file_charset': кодировка, используемая для чтения файлов шаблонов на диске.

    По умолчанию 'utf-8'.

  • 'libraries': словарь меток и точечных путей Python к модулям тегов шаблонов для регистрации в шаблоном движке. Это можно использовать для добавления новых библиотек или предоставления альтернативных меток для существующих. Например:

    OPTIONS = {
        "libraries": {
            "myapp_tags": "path.to.myapp.tags",
            "admin.urls": "django.contrib.admin.templatetags.admin_urls",
        },
    }
    

    Библиотеки могут загружаться путём передачи соответствующего ключа словаря тегу {% load %}.

  • 'builtins': список точечных путей Python к модулям тегов шаблонов для добавления в встроенные. Например:

    OPTIONS = {
        "builtins": ["myapp.builtins"],
    }
    

    Теги и фильтры из встроенных библиотек могут использоваться без предварительного вызова тега {% load %}.

class Jinja2 [source]

Требуется установка Jinja2:

$ python -m pip install Jinja2
...\> py -m pip install Jinja2

Установите BACKEND в 'django.template.backends.jinja2.Jinja2' для настройки движка Jinja2.

Когда APP_DIRS равно True, Jinja2 движки ищут шаблоны в подкаталоге jinja2 установленных приложений.

Самый важный элемент в OPTIONS — 'environment'. Это точечный путь Python к вызываемой функции, возвращающей среду Jinja2. По умолчанию 'jinja2.Environment'. Django вызывает эту функцию и передаёт другие параметры в качестве ключевых аргументов. Кроме того, Django добавляет значения по умолчанию, которые отличаются от значений Jinja2 для некоторых параметров:

  • 'autoescape': True
  • 'loader': загрузчик, настроенный для DIRS и APP_DIRS
  • 'auto_reload': settings.DEBUG
  • 'undefined': DebugUndefined if settings.DEBUG else Undefined

Jinja2 движки также принимают следующие OPTIONS:

  • 'context_processors': список точечных путей Python к вызываемым функциям, которые используются для заполнения контекста при рендеринге шаблона с запросом. Эти вызываемые функции принимают объект запроса в качестве аргумента и возвращают dict элементов, которые нужно объединить в контекст.

    По умолчанию пустой список.

    Использование процессоров контекста с шаблонами Jinja2 не рекомендуется.

    Процессоры контекста полезны для шаблонов Django, потому что шаблоны Django не поддерживают вызов функций с аргументами. Поскольку Jinja2 не имеет этого ограничения, рекомендуется поместить функцию, которую вы использовали бы в качестве процессора контекста, в глобальные переменные, доступные в шаблоне, используя jinja2.Environment как описано ниже. Затем вы можете вызвать эту функцию в шаблоне:

    {{ function(request) }}
    

    Некоторые процессоры контекста шаблонов Django возвращают фиксированное значение. Для шаблонов Jinja2 этот уровень косвенности не нужен, поскольку вы можете добавлять константы непосредственно в jinja2.Environment.

    Исходное применение добавления процессоров контекста для Jinja2 включало:

    • Произведение дорогостоящих вычислений, зависящих от запроса.
    • Необходимость результата в каждом шаблоне.
    • Использование результата несколько раз в каждом шаблоне.

    Если не все эти условия выполнены, передача функции в шаблон более соответствует дизайну Jinja2.

Настройка по умолчанию намеренно минимизирована. Если шаблон рендерится с запросом (например, при использовании render()), бэкенд Jinja2 добавляет глобальные переменные request, csrf_input, и csrf_token в контекст. Помимо этого, этот бэкенд не создаёт среду Django-стиля. Он не знает о фильтрах и тегах Django. Чтобы использовать API Django, вы должны настроить их в среде.

Например, вы можете создать myproject/jinja2.py с таким содержимым:

from django.templatetags.static import static
from django.urls import reverse

from jinja2 import Environment


def environment(**options):
    env = Environment(**options)
    env.globals.update(
        {
            "static": static,
            "url": reverse,
        }
    )
    return env

и установить параметр 'environment' на 'myproject.jinja2.environment'.

Затем вы можете использовать следующие конструкции в шаблонах Jinja2:

<img src="{{ static('path/to/company-logo.png') }}" alt="Company Logo">

<a href="{{ url('admin:index') }}">Administration</a>

Концепции тегов и фильтров существуют как в языке шаблонов Django, так и в Jinja2, но используются по-разному. Поскольку Jinja2 поддерживает передачу аргументов в вызываемые функции в шаблонах, многие функции, которые требуют тега или фильтра в шаблонах Django, могут быть реализованы путём вызова функции в шаблонах Jinja2, как показано в примере выше. Глобальное пространство имён Jinja2 избавляет от необходимости процессоров контекста шаблонов Django. В языке шаблонов Django нет аналога тестов Jinja2.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.1/topics/templates/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API