Spec-Zone.ru › Django 1.8

Шаблоны

В качестве веб-фреймворка 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.

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

Поддержка нескольких движков шаблонов и настройка TEMPLATES были добавлены в Django 1.8.

Настройка

Движки шаблонов настраиваются с помощью настройки 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, dirs=_dirs_undefined, using=None) [source]

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

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

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

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

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

Параметр dirs был добавлен.

Устарело начиная с версии 1.8: Параметр dirs был устаревшим.

Параметр using был добавлен.

get_template() возвращает зависимый от бэкенда Template вместо django.template.Template.

select_template(template_name_list, dirs=_dirs_undefined, using=None) [source]

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

Параметр dirs был добавлен.

Устарело начиная с версии 1.8: Параметр dirs был устаревшим.

Параметр using был добавлен.

select_template() возвращает зависимый от бэкенда Template вместо django.template.Template.

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

exception TemplateDoesNotExist [source]

Это исключение возникает, когда шаблон не найден.

exception TemplateSyntaxError [source]

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

Объекты 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, что и выше, будет попытка загрузить следующие шаблоны:

  • /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, context_instance=_context_instance_undefined, request=None, using=None) [source]

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

template_name
Имя шаблона для загрузки и рендеринга. Если это список имён шаблонов, Django использует select_template() вместо get_template() для поиска шаблона.
context

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

Аргумент context раньше назывался dictionary. Это имя устарело в Django 1.8 и будет удалено в Django 1.10.

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

context_instance

Экземпляр Context или его подкласса (например, экземпляр RequestContext) для использования в качестве контекста шаблона.

Deprecated since version 1.8: Аргумент context_instance устарел. Используйте context и, при необходимости, request.

request

Необязательный экземпляр HttpRequest, который будет доступен во время процесса рендеринга шаблона.

Аргумент request был добавлен.

См. также обёртки render() и render_to_response(), которые вызывают 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 [source]

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

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

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

  • 'allowed_include_roots': список строк, представляющих разрешенные префиксы для тега {% ssi %} шаблона. Это мера безопасности, чтобы авторы шаблонов не могли получить доступ к файлам, к которым им не следует иметь доступ.

    Например, если 'allowed_include_roots' равно ['/home/html', '/var/www'], тогда {% ssi /home/html/foo.txt %} будет работать, но {% ssi /etc/passwd %} — нет.

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

    Deprecated since version 1.8: allowed_include_roots устарел, так как тег {% ssi %} устарел.

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

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

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

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

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

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

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

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

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

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

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

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

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

class Jinja2 [source]

Требует установленного Jinja2:

$ 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 не создаёт среду с поддержкой Django. Он не знает о процессорах контекста, фильтрах и тегах Django. Чтобы использовать специфичные для Django API, вы должны настроить их в среде.

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

from __future__ import absolute_import  # Python 2 only

from django.contrib.staticfiles.storage import staticfiles_storage
from django.core.urlresolvers import reverse

from jinja2 import Environment


def environment(**options):
    env = Environment(**options)
    env.globals.update({
        'static': staticfiles_storage.url,
        '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>
END_OF_DOCUMENT_MARKER

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

Настраиваемые бэкэнды

Вот как реализовать настраиваемый бэкэнд шаблонов для использования другой системы шаблонов. Бэкэнд шаблона — это класс, который наследуется от django.template.backends.base.BaseEngine. Он должен реализовывать get_template() и необязательно from_string(). Вот пример для вымышленной foobar библиотеки шаблонов:

from django.template import TemplateDoesNotExist, TemplateSyntaxError
from django.template.backends.base import BaseEngine
from django.template.backends.utils import csrf_input_lazy, csrf_token_lazy

import foobar


class FooBar(BaseEngine):

    # Name of the subdirectory containing the templates for this engine
    # inside an installed application.
    app_dirname = 'foobar'

    def __init__(self, params):
        params = params.copy()
        options = params.pop('OPTIONS').copy()
        super(FooBar, self).__init__(params)

        self.engine = foobar.Engine(**options)


    def from_string(self, template_code):
        try:
          return Template(self.engine.from_string(template_code))
        except foobar.TemplateCompilationFailed as exc:
            raise TemplateSyntaxError(exc.args)

    def get_template(self, template_name):
        try:
            return Template(self.engine.get_template(template_name))
        except foobar.TemplateNotFound as exc:
            raise TemplateDoesNotExist(exc.args)
        except foobar.TemplateCompilationFailed as exc:
            raise TemplateSyntaxError(exc.args)


class Template(object):

    def __init__(self, template):
        self.template = template

    def render(self, context=None, request=None):
        if context is None:
            context = {}
        if request is not None:
            context['request'] = request
            context['csrf_input'] = csrf_input_lazy(request)
            context['csrf_token'] = csrf_token_lazy(request)
        return self.template.render(context)

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

Язык шаблонов 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 предоставляет множество встроенных обработчиков контекста. Реализация настраиваемого обработчика контекста так же проста, как определение функции.

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

Spec-Zone.ru

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