Spec-Zone.ru › Django 4.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. Это список конфигураций, по одной для каждого движка. Значение по умолчанию пустое. Значение settings.py , сгенерированное командой 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)

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

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

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

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

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

select_template(template_name_list, using=None)

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

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

exception TemplateDoesNotExist(msg, tried=None, backend=None, chain=None)

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

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

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

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

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

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

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

Если request предоставлен, он должен быть HttpRequest. Тогда движок должен сделать его, а также маркер 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 находит существующий шаблон, он прекращает поиск.

Подсказка

Вы можете использовать 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)

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

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

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

from django.template.loader import render_to_string
rendered = render_to_string('my_template.html', {'foo': 'bar'})

См. также сокращение render(), которое вызывает render_to_string() и передает результат в HttpResponse, пригодный для возврата из представления.

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

engines

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

from django.template import engines

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

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

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

class DjangoTemplates

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

Когда APP_DIRS имеет значение True, движки шаблонов ищут шаблоны в подкаталоге 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

Требуется пакет 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/4.1/topics/templates/

Spec-Zone.ru

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