Язык шаблонов Django: для программистов Python
Этот документ объясняет систему шаблонов Django с технической точки зрения — как она работает и как ее расширить. Если вы ищете только справочную информацию по синтаксису языка, см. Язык шаблонов Django.
Предполагается понимание шаблонов, контекстов, переменных, тегов и рендеринга. Начните с введения в язык шаблонов Django, если вы не знакомы с этими понятиями.
Обзор
Использование системы шаблонов на Python — трехступенчатый процесс:
- Вы настраиваете
Engine. - Вы компилируете код шаблона в
Template. - Вы рендерите шаблон с помощью
Context.
Проекты Django обычно полагаются на API высокого уровня, независимые от бэкенда на каждом из этих шагов вместо API системы шаблонов низкого уровня:
- Для каждого
DjangoTemplatesбэкенда в настройкеTEMPLATES, Django инициализируетEngine.DjangoTemplatesоборачиваетEngineи адаптирует его к обычному API бэкенда шаблонов. - Модуль
django.template.loaderпредоставляет функции, такие какget_template()для загрузки шаблонов. Они возвращают обёртку над фактическимdjango.template.Template. - Полученный на предыдущем шаге объект имеет метод
render(), который обрабатывает контекст и, возможно, запрос вContextи делегирует рендеринг нашемуTemplate.
Настройка движка
Если вы просто используете бэкенд DjangoTemplates, этот документ, вероятно, не то, что вам нужно. Экземпляр класса нижеописанного класса доступен через атрибут бэкенда, а любые указанные ниже значения по умолчанию переопределяются тем, что передаётся DjangoTemplates.
-
class Engine(dirs=None, app_dirs=False, context_processors=None, debug=False, loaders=None, string_if_invalid='', file_charset='utf-8', libraries=None, builtins=None, autoescape=True)[source] -
При создании экземпляра все аргументы должны передаваться в качестве именованных аргументов:
-
dirs— список каталогов, в которых движок должен искать файлы шаблонов. Он используется для настройкиfilesystem.Loader.По умолчанию пустой список.
-
app_dirsвлияет только на значение по умолчаниюloaders. См. ниже.По умолчанию
False. -
autoescapeопределяет, включена ли автоматическая экранировка HTML.По умолчанию
True.Предупреждение
Установите его только в
False, если вы рендерите не HTML-шаблоны!Добавлено в Django 1.10:Параметр
autoescapeбыл добавлен. -
context_processors— список имён функций Python, используемых для заполнения контекста, когда шаблон рендерится с запросом. Эти функции принимают объект запроса в качестве аргумента и возвращают словарь элементов, которые должны быть объединены в контекст.По умолчанию пустой список.
См.
RequestContextдля дополнительной информации. -
debug— логический флаг, включающий/выключающий режим отладки шаблонов. Если он равенTrue, движок шаблонов будет хранить дополнительную отладочную информацию, которая может быть использована для отображения подробного отчета об ошибках, возникающих во время рендеринга шаблонов.По умолчанию
False. -
loaders— список классов загрузчиков шаблонов, указанных в виде строк. Каждый классLoaderзнает, как импортировать шаблоны из определенного источника. Допускается использование кортежей вместо строк. Первый элемент кортежа должен быть именем классаLoader, последующие элементы передаются загрузчикуLoaderво время инициализации.По умолчанию список, содержащий:
'django.template.loaders.filesystem.Loader'-
'django.template.loaders.app_directories.Loader'только еслиapp_dirsравенTrue.
См. Типы загрузчиков для получения подробностей.
-
string_if_invalid— строковое значение, которое должна использовать система шаблонов для неверных (например, неверно написанных) переменных.По умолчанию пустая строка.
См. Обработка неверных переменных шаблонов для подробностей.
-
file_charset— кодировка, используемая для чтения файлов шаблонов на диске.По умолчанию
'utf-8'. -
'libraries': Словарь меток и имён Python-модулей тегов шаблонов, которые будут зарегистрированы в движке шаблонов. Это используется для добавления новых библиотек или предоставления альтернативных меток для существующих. Например:Engine( libraries={ 'myapp_tags': 'path.to.myapp.tags', 'admin.urls': 'django.contrib.admin.templatetags.admin_urls', }, )Библиотеки могут загружаться путём передачи соответствующего ключа словаря тегу
{% load %}. -
'builtins': Список имён Python-модулей тегов шаблонов для добавления в встроенные. Например:Engine( builtins=['myapp.builtins'], )Теги и фильтры из встроенных библиотек могут использоваться без предварительного вызова тега
{% load %}.
-
Аргументы libraries и builtins были добавлены.
-
static Engine.get_default()[source] -
Когда проект Django настраивает один и только один движок
DjangoTemplates, этот метод возвращает основнойEngine. В других случаях он генерируетImproperlyConfigured.Это необходимо для сохранения API, которые полагаются на глобально доступный, неявным образом настроенный движок. Любое другое использование настоятельно не рекомендуется.
-
Engine.from_string(template_code)[source] -
Компилирует заданный код шаблона и возвращает объект
Template.
-
Engine.get_template(template_name)[source] -
Загружает шаблон с заданным именем, компилирует его и возвращает объект
Template.
-
Engine.select_template(self, template_name_list)[source] -
Подобно
get_template(), за исключением того, что он принимает список имён и возвращает первый найденный шаблон.
Загрузка шаблона
Рекомендуемый способ создания Template — вызов методов-фабрик Engine: get_template(), select_template() и from_string().
В проекте Django, где настройка TEMPLATES определяет ровно один DjangoTemplates движок, можно создать Template напрямую.
-
class Template[source] -
Этот класс находится в
django.template.Template. Конструктор принимает один аргумент — исходный код шаблона:from django.template import Template template = Template("My name is {{ my_name }}.")
За кулисами
Система анализирует исходный код вашего шаблона только один раз — при создании объекта Template. После этого он хранится в виде внутренней структуры дерева для повышения производительности.
Даже сам процесс анализа происходит довольно быстро. Большая часть анализа выполняется с помощью одного вызова одного короткого регулярного выражения.
Отображение контекста
После получения скомпилированного объекта Template можно отобразить контекст с его помощью. Один и тот же шаблон можно повторно использовать для отображения с разными контекстами.
-
class Context(dict_=None)[source] -
Конструктор
django.template.Contextпринимает необязательный аргумент — словарь, сопоставляющий имена переменных с их значениями.Подробнее см. Работа с объектами Context ниже.
-
Template.render(context)[source] -
Вызовите метод
render()объектаTemplateс объектомContextдля заполнения шаблона:>>> from django.template import Context, Template >>> template = Template("My name is {{ my_name }}.") >>> context = Context({"my_name": "Adrian"}) >>> template.render(context) "My name is Adrian." >>> context = Context({"my_name": "Dolores"}) >>> template.render(context) "My name is Dolores."
Переменные и поиски
Имена переменных должны состоять из любых букв (A-Z), любых цифр (0-9), символа подчеркивания (но они не должны начинаться с символа подчеркивания) или точки.
Точки имеют особое значение в отображении шаблонов. Точка в имени переменной означает поиск. В частности, когда система шаблонов встречает точку в имени переменной, она выполняет следующие поиски в указанном порядке:
- Поиск по словарю. Пример:
foo["bar"] - Поиск по атрибуту. Пример:
foo.bar - Поиск по индексу списка. Пример:
foo[bar]
Обратите внимание, что «bar» в выражении шаблона, например, {{ foo.bar }}, будет интерпретироваться как буквальная строка, а не как значение переменной «bar», если таковая существует в контексте шаблона.
Система шаблонов использует первый тип поиска, который работает. Это логика короткого замыкания. Вот несколько примеров:
>>> from django.template import Context, Template
>>> t = Template("My name is {{ person.first_name }}.")
>>> d = {"person": {"first_name": "Joe", "last_name": "Johnson"}}
>>> t.render(Context(d))
"My name is Joe."
>>> class PersonClass: pass
>>> p = PersonClass()
>>> p.first_name = "Ron"
>>> p.last_name = "Nasty"
>>> t.render(Context({"person": p}))
"My name is Ron."
>>> t = Template("The first stooge in the list is {{ stooges.0 }}.")
>>> c = Context({"stooges": ["Larry", "Curly", "Moe"]})
>>> t.render(c)
"The first stooge in the list is Larry."
Если какая-либо часть переменной является вызываемой, система шаблонов попытается вызвать её. Пример:
>>> class PersonClass2:
... def name(self):
... return "Samantha"
>>> t = Template("My name is {{ person.name }}.")
>>> t.render(Context({"person": PersonClass2}))
"My name is Samantha."
Вызываемые переменные немного сложнее, чем переменные, требующие только прямых поисков. Вот некоторые моменты, которые следует учитывать:
-
Если при вызове переменной возникает исключение, исключение будет распространяться, если у исключения нет атрибута
silent_variable_failure, значение которого равноTrue. Если у исключения *есть* атрибутsilent_variable_failure, значение которого равноTrue, переменная будет отображена как значение конфигурационного параметра движкаstring_if_invalid(по умолчанию — пустая строка). Пример:>>> t = Template("My name is {{ person.first_name }}.") >>> class PersonClass3: ... def first_name(self): ... raise AssertionError("foo") >>> p = PersonClass3() >>> t.render(Context({"person": p})) Traceback (most recent call last): ... AssertionError: foo >>> class SilentAssertionError(Exception): ... silent_variable_failure = True >>> class PersonClass4: ... def first_name(self): ... raise SilentAssertionError >>> p = PersonClass4() >>> t.render(Context({"person": p})) "My name is ."Обратите внимание, что
django.core.exceptions.ObjectDoesNotExist, который является базовым классом для всех исключений API базы данных Django, имеетsilent_variable_failure = True. Таким образом, если вы используете шаблоны Django с объектами модели Django, исключениеDoesNotExistбудет игнорироваться. - Переменная может быть вызвана только если она не требует аргументов. В противном случае система вернет значение параметра движка
string_if_invalid.
-
Очевидно, что вызов некоторых переменных может иметь побочные эффекты, и позволять системе шаблонов получать к ним доступ было бы либо глупо, либо небезопасно.
Хороший пример — метод
delete()для каждого объекта модели Django. Система шаблонов не должна иметь права делать что-то подобное:I will now delete this valuable data. {{ data.delete }}Чтобы предотвратить это, установите атрибут
alters_dataна вызываемую переменную. Система шаблонов не будет вызывать переменную, если у неё установлен атрибутalters_data=True, и вместо этого заменит переменную наstring_if_invalid, безусловно. Динамически сгенерированные методыdelete()иsave()для объектов модели Django автоматически получают атрибутalters_data=True. Пример:def sensitive_function(self): self.database_record.delete() sensitive_function.alters_data = True - Иногда вам может потребоваться отключить эту функцию по другим причинам и указать системе шаблонов оставить переменную невызванной независимо от чего. Для этого установите атрибут
do_not_call_in_templatesвызываемой переменной со значениемTrue. Система шаблонов затем будет действовать так, как будто ваша переменная не вызываемая (позволяя, например, получать доступ к атрибутам вызываемой переменной).
Как обрабатываются недопустимые переменные шаблонов
В целом, если переменная не существует, система шаблонов вставляет значение конфигурационного параметра движка string_if_invalid, которое по умолчанию равно '' (пустая строка).
Фильтры, применяемые к недопустимой переменной, будут применяться только если string_if_invalid установлено в '' (пустая строка). Если string_if_invalid установлено в какое-либо другое значение, фильтры переменных будут проигнорированы.
Это поведение немного отличается для тегов шаблонов if, for и regroup. Если недопустимая переменная передается одному из этих тегов шаблонов, переменная будет интерпретироваться как None. Фильтры всегда применяются к недопустимым переменным внутри этих тегов шаблонов.
Если string_if_invalid содержит '%s', маркер формата будет заменен именем недопустимой переменной.
Только для отладки!
Хотя string_if_invalid может быть полезным инструментом для отладки, плохо использовать его в качестве «стандартного параметра по умолчанию для разработки».
Многие шаблоны, включая те, что используются в админском интерфейсе, полагаются на то, что система шаблонов молчит, когда встречается несуществующая переменная. Если вы присвоите значение, отличное от '' параметру string_if_invalid, у вас возникнут проблемы с отображением этих шаблонов и сайтов.
В целом, string_if_invalid следует использовать только для отладки определенной проблемы с шаблоном, а затем очистить его после завершения отладки.
Встроенные переменные
Каждый контекст содержит True, False и None. Как ожидалось, эти переменные разрешаются соответствующими объектами Python.
Ограничения использования строковых литералов
Язык шаблонов Django не умеет экранировать символы, используемые для собственной синтаксической конструкции. Например, тег templatetag требуется, если нужно вывести последовательности символов, такие как {% и %}.
Аналогичная проблема возникает, если вы хотите включить эти последовательности в аргументы фильтров или тегов шаблонов. Например, при анализе тега блока Django анализатор шаблонов ищет первое вхождение %} после {%. Это препятствует использованию "%}" в качестве строкового литерала. Например, будет генерироваться ошибка TemplateSyntaxError для следующих выражений:
{% include "template.html" tvar="Some string literal with %} in it." %}
{% with tvar="Some string literal with %} in it." %}{% endwith %}
Та же проблема может возникнуть при использовании зарезервированной последовательности в аргументах фильтра:
{{ some.variable|default:"}}" }}
Если вам нужно использовать строки с этими последовательностями, храните их в переменных шаблона или используйте пользовательский тег или фильтр шаблона, чтобы обойти это ограничение.
Работа с объектами Context
Большую часть времени вы будете создавать объекты Context, передавая в Context() полностью заполненный словарь. Но вы также можете добавлять и удалять элементы из объекта Context после его создания, используя стандартную синтаксическую конструкцию словарей:
>>> from django.template import Context
>>> c = Context({"foo": "bar"})
>>> c['foo']
'bar'
>>> del c['foo']
>>> c['foo']
Traceback (most recent call last):
...
KeyError: 'foo'
>>> c['newvariable'] = 'hello'
>>> c['newvariable']
'hello'
-
Context.get(key, otherwise=None) -
Возвращает значение для
key, еслиkeyесть в контексте, иначе возвращаетotherwise.
-
Context.setdefault(key, default=None) -
Добавлен в Django 1.9.
Если
keyнаходится в контексте, возвращает его значение. В противном случае вставляетkeyсо значениемdefaultи возвращаетdefault.
-
Context.pop()
-
Context.push()
-
exception ContextPopException[source]
Объект Context является стеком. То есть, вы можете pop() и pop() его. Если вы pop() слишком много, он поднимет исключение django.template.ContextPopException.
>>> c = Context()
>>> c['foo'] = 'first level'
>>> c.push()
{}
>>> c['foo'] = 'second level'
>>> c['foo']
'second level'
>>> c.pop()
{'foo': 'second level'}
>>> c['foo']
'first level'
>>> c['foo'] = 'overwritten'
>>> c['foo']
'overwritten'
>>> c.pop()
Traceback (most recent call last):
...
ContextPopException
Вы также можете использовать push() как менеджер контекста для обеспечения вызова соответствующего pop().
>>> c = Context() >>> c['foo'] = 'first level' >>> with c.push(): ... c['foo'] = 'second level' ... c['foo'] 'second level' >>> c['foo'] 'first level'
Все аргументы, переданные push(), будут переданы конструктору dict, используемому для создания нового уровня контекста.
>>> c = Context() >>> c['foo'] = 'first level' >>> with c.push(foo='second level'): ... c['foo'] 'second level' >>> c['foo'] 'first level'
-
Context.update(other_dict)[source]
В дополнение к push() и pop(), объект Context также определяет метод update(). Он работает как push(), но принимает словарь в качестве аргумента и помещает этот словарь на стек вместо пустого.
>>> c = Context()
>>> c['foo'] = 'first level'
>>> c.update({'foo': 'updated'})
{'foo': 'updated'}
>>> c['foo']
'updated'
>>> c.pop()
{'foo': 'updated'}
>>> c['foo']
'first level'
Как и push(), вы можете использовать update() в качестве менеджера контекста, чтобы обеспечить вызов соответствующего pop().
>>> c = Context()
>>> c['foo'] = 'first level'
>>> with c.update({'foo': 'second level'}):
... c['foo']
'second level'
>>> c['foo']
'first level'
Была добавлена возможность использования update() в качестве менеджера контекста.
Использование Context в качестве стека полезно в некоторых пользовательских тегах шаблонов.
-
Context.flatten()
Используя метод flatten(), вы можете получить весь стек Context как один словарь, включая встроенные переменные.
>>> c = Context()
>>> c['foo'] = 'first level'
>>> c.update({'bar': 'second level'})
{'bar': 'second level'}
>>> c.flatten()
{'True': True, 'None': None, 'foo': 'first level', 'False': False, 'bar': 'second level'}
Метод flatten() также используется внутри для сравнения объектов Context.
>>> c1 = Context()
>>> c1['foo'] = 'first level'
>>> c1['bar'] = 'second level'
>>> c2 = Context()
>>> c2.update({'bar': 'second level', 'foo': 'first level'})
{'foo': 'first level', 'bar': 'second level'}
>>> c1 == c2
True
Результат от flatten() может быть полезен в тестах для сравнения Context с dict:
class ContextTest(unittest.TestCase):
def test_against_dictionary(self):
c1 = Context()
c1['update'] = 'value'
self.assertEqual(c1.flatten(), {
'True': True,
'None': None,
'False': False,
'update': 'value',
})
Использование RequestContext
-
class RequestContext(request, dict_=None, processors=None)[source]
Django поставляется со специальным классом Context, django.template.RequestContext, который немного отличается от обычного django.template.Context. Первое отличие заключается в том, что он принимает HttpRequest в качестве первого аргумента. Например:
c = RequestContext(request, {
'foo': 'bar',
})
Второе отличие заключается в том, что он автоматически заполняет контекст несколькими переменными в соответствии с опцией конфигурации движка context_processors.
Опция context_processors — это список вызываемых объектов (**обработчики контекста**), которые принимают объект запроса в качестве аргумента и возвращают словарь элементов, которые должны быть объединены в контекст. В файле настроек по умолчанию сгенерированного файла настроек в стандартном движке шаблонов содержатся следующие обработчики контекста:
[
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
]
Помимо этого, RequestContext всегда включает 'django.template.context_processors.csrf'. Это обработчик контекста, связанный с безопасностью, необходимый для админской панели и других приложений из пакета contrib, и в случае случайной неправильной конфигурации он намеренно жестко запрограммирован и не может быть выключен в опции context_processors.
Каждый обработчик применяется в порядке. Это означает, что если один обработчик добавляет переменную в контекст, а второй обработчик добавляет переменную с тем же именем, второй перепишет первый. Обработчики по умолчанию описаны ниже.
Когда применяются обработчики контекста
Обработчики контекста применяются поверх данных контекста. Это означает, что обработчик контекста может перезаписать переменные, которые вы предоставили в вашем Context или RequestContext, поэтому позаботьтесь об избежании имен переменных, которые перекрываются переменными, предоставляемыми обработчиками контекста.
Если вы хотите, чтобы данные контекста имели приоритет над обработчиками контекста, используйте следующий шаблон:
from django.template import RequestContext
request_context = RequestContext(request)
request_context.push({"my_name": "Adrian"})
Django делает это, чтобы позволить данным контекста переопределять обработчики контекста в API, таких как render() и TemplateResponse.
Также вы можете предоставить RequestContext список дополнительных обработчиков, используя необязательный третий позиционный аргумент processors. В этом примере экземпляр RequestContext получает переменную ip_address.
from django.http import HttpResponse
from django.template import RequestContext, Template
def ip_address_processor(request):
return {'ip_address': request.META['REMOTE_ADDR']}
def client_ip_view(request):
template = Template('{{ title }}: {{ ip_address }}')
context = RequestContext(request, {
'title': 'Your IP Address',
}, [ip_address_processor])
return HttpResponse(template.render(context))
Встроенные обработчики контекста шаблонов
Вот что делает каждый из встроенных обработчиков:
django.contrib.auth.context_processors.auth
-
auth()[source]
Если этот обработчик включён, каждый RequestContext будет содержать эти переменные:
-
user– Экземплярauth.User, представляющий текущего пользователя, вошедшего в систему (или экземплярAnonymousUser, если клиент не вошёл в систему). -
perms– Экземплярdjango.contrib.auth.context_processors.PermWrapper, представляющий разрешения текущего пользователя, вошедшего в систему.
django.template.context_processors.debug
-
debug()[source]
Если этот обработчик включен, каждый RequestContext будет содержать эти две переменные — но только если ваша настройка DEBUG установлена в True и IP-адрес запроса (request.META['REMOTE_ADDR']) находится в настройке INTERNAL_IPS:
-
debug–True. Вы можете использовать это в шаблонах для проверки, находитесь ли вы в режимеDEBUG. -
sql_queries– Список словарей{'sql': ..., 'time': ...}, представляющих каждую SQL-запрос, выполненную до сих пор в ходе запроса, и сколько времени на это потребовалось. Список упорядочен по имени базы данных, а затем по запросу. Он генерируется лениво при обращении.
В более ранних версиях включались только запросы для базы данных по умолчанию.
django.template.context_processors.i18n
Если этот обработчик включён, каждый RequestContext будет содержать эти две переменные:
-
LANGUAGES– Значение настройкиLANGUAGES. -
LANGUAGE_CODE–request.LANGUAGE_CODE, если он существует. В противном случае значение настройкиLANGUAGE_CODE.
См. Международный и локальный перевод для получения дополнительной информации.
django.template.context_processors.media
Если этот обработчик включён, каждый RequestContext будет содержать переменную MEDIA_URL, предоставляющую значение настройки MEDIA_URL.
django.template.context_processors.static
-
static()[source]
Если этот обработчик включён, каждый RequestContext будет содержать переменную STATIC_URL, предоставляющую значение настройки STATIC_URL.
django.template.context_processors.csrf
Этот обработчик добавляет маркер, необходимый тегу шаблона csrf_token для защиты от межсайтовых поддельных запросов.
django.template.context_processors.request
Если этот обработчик включён, каждый RequestContext будет содержать переменную request, которая является текущим HttpRequest.
django.template.context_processors.tz
-
tz()[source]
Если этот обработчик включён, каждый RequestContext будет содержать переменную TIME_ZONE, предоставляющую имя текущей активной временной зоны.
django.contrib.messages.context_processors.messages
Если этот обработчик включён, каждый RequestContext будет содержать эти две переменные:
-
messages– Список сообщений (в виде строк), установленных с помощью фреймворка сообщений. -
DEFAULT_MESSAGE_LEVELS– Сопоставление имён уровней сообщений с их числовыми значениями.
Создание собственных процессоров контекста
Процессор контекста имеет очень простой интерфейс: это функция Python, которая принимает один аргумент, объект HttpRequest, и возвращает словарь, который добавляется в контекст шаблона. Каждый процессор контекста обязательно должен возвращать словарь.
Пользовательские процессоры контекста могут находиться в любом месте вашей кодовой базы. Django заботится только о том, чтобы ваши пользовательские процессоры контекста были указаны в опции 'context_processors' в настройке TEMPLATES — или в аргументе context_processors метода Engine, если вы используете его напрямую.
Загрузка шаблонов
Как правило, вы будете хранить шаблоны в файлах на вашей файловой системе, а не использовать низкоуровневый API Template самостоятельно. Сохраняйте шаблоны в каталоге, указанном как каталог шаблонов.
Django ищет каталоги шаблонов в ряде мест, в зависимости от настроек загрузки шаблонов (см. «Типы загрузчиков» ниже), но самый простой способ указать каталоги шаблонов — использовать опцию DIRS.
Опция DIRS
Укажите Django свои каталоги шаблонов, используя опцию DIRS в настройке TEMPLATES в вашем файле настроек — или в аргументе dirs метода Engine. Это должно быть списком строк, содержащих полные пути к каталогам шаблонов:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
'/home/html/templates/lawrence.com',
'/home/html/templates/default',
],
},
]
Шаблоны могут быть расположены где угодно, при условии, что каталоги и шаблоны доступны веб-серверу. Они могут иметь любое расширение, например .html или .txt, или вообще не иметь расширения.
Обратите внимание, что эти пути должны использовать обратные слэши в стиле Unix, даже в Windows.
Типы загрузчиков
По умолчанию Django использует загрузчик шаблонов на основе файловой системы, но Django предоставляет несколько других загрузчиков шаблонов, которые умеют загружать шаблоны из других источников.
Некоторые из этих других загрузчиков по умолчанию отключены, но вы можете их активировать, добавив опцию 'loaders' к вашему бэкенду DjangoTemplates в настройке TEMPLATES или передав аргумент loaders методу Engine. loaders должен быть списком строк или кортежей, где каждый из них представляет класс загрузчика шаблонов. Вот загрузчики шаблонов, которые поставляются с Django:
django.template.loaders.filesystem.Loader
-
class filesystem.Loader -
Загружает шаблоны с файловой системы в соответствии с
DIRS.Этот загрузчик включён по умолчанию. Однако он не найдёт никаких шаблонов, пока вы не зададите
DIRSнепустым списком:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], }]
django.template.loaders.app_directories.Loader
-
class app_directories.Loader -
Загружает шаблоны из приложений Django с файловой системы. Для каждого приложения в
INSTALLED_APPS, загрузчик ищет подкаталогtemplates. Если каталог существует, Django ищет шаблоны в нём.Это означает, что вы можете хранить шаблоны вместе со своими отдельными приложениями. Это также упрощает распространение приложений Django с шаблонами по умолчанию.
Например, для этой настройки:
INSTALLED_APPS = ['myproject.polls', 'myproject.music']
…тогда
get_template('foo.html')будет искатьfoo.htmlв этих каталогах в этом порядке:/path/to/myproject/polls/templates//path/to/myproject/music/templates/
… и воспользуется первым найденным.
Порядок
INSTALLED_APPSимеет значение! Например, если вы хотите настроить административную панель Django, вы можете переопределить стандартный шаблонadmin/base_site.htmlизdjango.contrib.adminсвоим собственнымadmin/base_site.htmlвmyproject.polls. Затем вы должны убедиться, что вашеmyproject.pollsстоит передdjango.contrib.adminвINSTALLED_APPS, иначеdjango.contrib.adminбудут загружены первыми, и ваши будут проигнорированы.Обратите внимание, что загрузчик выполняет оптимизацию при первом запуске: он кеширует список пакетов
INSTALLED_APPS, которые имеют подкаталогtemplates.Вы можете включить этот загрузчик, просто задав
APP_DIRSзначениеTrue.TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'APP_DIRS': True, }]
django.template.loaders.eggs.Loader
-
class eggs.Loader -
Устарело начиная с версии 1.9: Распространение приложений в виде пакетов eggs не рекомендуется.
Точно так же, как и
app_directoriesвыше, но он загружает шаблоны из Python-пакетов eggs, а не с файловой системы.Этот загрузчик по умолчанию отключён.
django.template.loaders.cached.Loader
-
class cached.Loader -
По умолчанию система шаблонизации будет читать и компилировать ваши шаблоны каждый раз, когда они требуются для рендеринга. Хотя система шаблонизации Django довольно быстрая, накладные расходы от чтения и компиляции шаблонов могут накапливаться.
Загрузчик кэшированных шаблонов — это загрузчик на основе класса, который вы настраиваете с помощью списка других загрузчиков, которые он должен обернуть. Обернутые загрузчики используются для поиска неизвестных шаблонов, когда они встречаются впервые. Загрузчик кэша затем сохраняет скомпилированные
Templateв памяти. Кэшированный экземплярTemplateвозвращается для последующих запросов на загрузку того же шаблона.Например, для включения кэширования шаблонов с загрузчиками
filesystemиapp_directoriesвы можете использовать следующие настройки:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'OPTIONS': { 'loaders': [ ('django.template.loaders.cached.Loader', [ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ]), ], }, }]Примечание
Все встроенные теги Django шаблонов безопасны для использования с кэшированным загрузчиком, но если вы используете пользовательские теги шаблонов, которые происходят из пакетов сторонних разработчиков или которые вы написали сами, вы должны убедиться, что реализация
Nodeдля каждого тега является потокобезопасной. Дополнительную информацию см. в разделе о потоковой безопасности тегов шаблонов.Этот загрузчик по умолчанию отключён.
django.template.loaders.locmem.Loader
-
class locmem.Loader -
Загружает шаблоны из словаря Python. Это полезно для тестирования.
Этот загрузчик принимает словарь шаблонов в качестве первого аргумента:
TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'OPTIONS': { 'loaders': [ ('django.template.loaders.locmem.Loader', { 'index.html': 'content here', }), ], }, }]Этот загрузчик по умолчанию отключён.
Django использует загрузчики шаблонов в порядке согласно опции 'loaders'. Он использует каждый загрузчик до тех пор, пока один из них не найдёт совпадение.
Пользовательские загрузчики шаблонов
Можно загружать шаблоны из дополнительных источников с помощью пользовательских загрузчиков шаблонов. Пользовательские классы Loader должны наследоваться от django.template.loaders.base.Loader и определять методы get_contents() и get_template_sources().
В предыдущих версиях Django пользовательские загрузчики определяли один метод: load_template_source().
Методы загрузчика
-
class Loader[source] -
Загружает шаблоны из заданного источника, такого как файловая система или база данных.
-
get_template_sources(template_name)[source] -
Метод, который принимает
template_nameи возвращаетOriginобъекты для каждого возможного источника.Например, загрузчик файловой системы может получить
'index.html'в качестве аргументаtemplate_name. Этот метод вернёт объекты origin для полного пути кindex.htmlв каждом каталоге шаблонов, который просматривает загрузчик.Методу не нужно проверять, существует ли шаблон по указанному пути, но он должен гарантировать, что путь является допустимым. Например, загрузчик файловой системы проверяет, что путь находится в пределах допустимого каталога шаблонов.
-
get_contents(origin) -
Возвращает содержимое шаблона для заданного объекта
Origin.Здесь загрузчик файловой системы читает содержимое из файловой системы, а загрузчик базы данных — из базы данных. Если соответствующего шаблона не существует, должно быть выброшено исключение
TemplateDoesNotExist.
-
get_template(template_name, skip=None)[source] -
Возвращает объект
Templateдля заданногоtemplate_name, перебирая результаты изget_template_sources()и вызываяget_contents(). Это возвращает первый совпавший шаблон. Если шаблон не найден, генерируется исключениеTemplateDoesNotExist.Необязательный аргумент
skip— список объектов origin, которые следует игнорировать при расширении шаблонов. Это позволяет шаблонам расширять другие шаблоны с тем же именем. Это также используется для предотвращения рекурсивных ошибок.В общем случае достаточно определить
get_template_sources()иget_contents()для пользовательских загрузчиков шаблонов. Методget_template()обычно переопределять не нужно.
-
load_template_source(template_name, template_dirs=None)[source] -
Возвращает кортеж (
template_string,template_origin), гдеtemplate_string— строка, содержащая содержимое шаблона, аtemplate_origin— строка, определяющая источник шаблона. Загрузчик на основе файловой системы может вернуть полный путь к файлу в качествеtemplate_origin, например.template_dirs— необязательный аргумент, используемый для управления каталогами, которые будет искать загрузчик.Этот метод вызывается автоматически методом
load_template()и должен быть переопределён при написании пользовательских загрузчиков шаблонов.Устарело начиная с версии 1.9: Пользовательские загрузчики должны использовать
get_template()иget_contents()вместо этого.
-
load_template(template_name, template_dirs=None)[source] -
Возвращает кортеж (
template,template_origin), гдеtemplate— объектTemplate, аtemplate_origin— строка, определяющая источник шаблона. Загрузчик на основе файловой системы может вернуть полный путь к файлу в качествеtemplate_origin, например.Устарело начиная с версии 1.9: Пользовательские загрузчики должны использовать
get_template()иget_contents()вместо этого.
-
Создание своего
Для примеров прочитайте исходный код встроенных загрузчиков Django.
Происхождение шаблона
Шаблоны имеют origin с атрибутами, зависящими от источника, из которого они загружены.
Django раньше создавал происхождение на основе django.template.loader.LoaderOrigin или django.template.base.StringOrigin. Теперь используется django.template.base.Origin.
-
class Origin[source] -
-
name -
Путь к шаблону, возвращаемый загрузчиком шаблонов. Для загрузчиков, которые читают из файловой системы, это полный путь к шаблону.
Если шаблон инициализирован непосредственно, а не через загрузчик шаблонов, это строковое значение
<unknown_source>.
-
template_name -
Относительный путь к шаблону, переданный в загрузчик шаблонов.
Если шаблон инициализирован непосредственно, а не через загрузчик шаблонов, это
None.
-
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.10/ref/templates/api/