Язык шаблонов 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.backends.django.Template, который оборачивает фактическийdjango.template.Template. - Полученный на предыдущем шаге
Templateимеет методrender(), который направляет контекст и, возможно, запрос вContextи делегирует рендеринг основномуTemplate.
Настройка движка
Если вы просто используете бэкенд DjangoTemplates, этот документ, вероятно, вам не нужен. Экземпляр класса Engine ниже доступен через атрибут engine этого бэкенда, и любые значения по умолчанию атрибутов ниже переопределяются тем, что передано 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] -
При создании экземпляра
Engineвсе аргументы должны передаваться в качестве именованных:-
dirs— список каталогов, в которых движок должен искать файлы исходного кода шаблонов. Он используется для настройкиfilesystem.Loader.По умолчанию пустой список.
-
app_dirsвлияет только на значение по умолчаниюloaders. См. ниже.По умолчанию
False. -
autoescapeуправляет тем, включена ли автоматическая экранизация HTML.По умолчанию
True.Предупреждение
Установите его только в значение
Falseесли вы рендерите не HTML-шаблоны!Добавлен в Django 1.10:Вариант
autoescapeбыл добавлен. -
context_processors— список имён Python-функций, которые используются для заполнения контекста, когда шаблон рендерится с запросом. Эти функции принимают объект запроса в качестве аргумента и возвращаютdictэлементов, которые будут объединены в контекст.По умолчанию пустой список.
См.
RequestContextдля получения дополнительной информации. -
debug— логическое значение, которое включает/выключает режим отладки шаблонов. Если онTrue, движок шаблонов будет сохранять дополнительную отладочную информацию, которая может быть использована для отображения подробного отчёта об исключениях, возникших во время рендеринга шаблонов.По умолчанию
False. -
loaders— список классов загрузчиков шаблонов, указанных в виде строк. Каждый классLoaderзнает, как импортировать шаблоны из определенного источника. Дополнительно может использоваться кортеж вместо строки. Первый элемент кортежа должен быть именем классаLoader, последующие элементы передаются классуLoaderпри инициализации.По умолчанию список, содержащий:
'django.template.loaders.filesystem.Loader'-
'django.template.loaders.app_directories.Loader'только тогда, когдаapp_dirsравноTrue.
Если
debugравноFalse, эти загрузчики оборачиваются вdjango.template.loaders.cached.Loader.См. Типы загрузчиков для получения подробностей.
Изменено в Django 1.11:Добавлена возможность включения кеширующего загрузчика шаблонов, когда
debugравноFalse. -
string_if_invalid— строковое значение, которое система шаблонов должна использовать для неверных (например, неправильно написанных) переменных.По умолчанию пустая строка.
См. Обработка неверных переменных шаблонов для получения подробностей.
-
file_charset— кодировка, используемая системой для чтения файлов шаблонов с диска.По умолчанию
'utf-8'. -
'libraries': Словарь меток и путей к модулям тегов шаблонов, которые необходимо зарегистрировать в движке шаблонов. Используется для добавления новых библиотек или предоставления альтернативных меток для существующих. Например:Engine( libraries={ 'myapp_tags': 'path.to.myapp.tags', 'admin.urls': 'django.contrib.admin.templatetags.admin_urls', }, )Библиотеки можно загрузить, передав соответствующий ключ словаря тегу
{% load %}. -
'builtins': Список путей к модулям тегов шаблонов для добавления в встроенные. Например:Engine( builtins=['myapp.builtins'], )Теги и фильтры из встроенных библиотек можно использовать, не вызывая предварительно тег
{% load %}.
-
-
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(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принимает необязательный аргумент — словарь, сопоставляющий имена переменных с их значениями.Подробнее см. Использование объектов контекста ниже.
-
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 базы данных DjangoDoesNotExist, имеет атрибут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 после его создания, используя стандартную синтаксис словарей:
>>> 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) -
Если
keyесть в контексте, возвращает его значение. В противном случае добавляетkeyсо значениемdefaultи возвращаетdefault.
-
Context.pop()
-
Context.push()
-
exception ContextPopException[source]
Объект Context представляет собой стек. То есть вы можете добавлять push() и удалять 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'
Использование 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 для защиты от межсайтовых поддельных запросов (CSRF).
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, или вообще не иметь расширения.
Обратите внимание, что эти пути должны использовать косые черты, даже в 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')], }]Вы также можете переопределить
'DIRS'и указать определённые каталоги для конкретного загрузчика файловой системы:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'OPTIONS': { 'loaders': [ ( 'django.template.loaders.filesystem.Loader', [os.path.join(BASE_DIR, 'templates')], ), ], }, }]Изменено в Django 1.11:Добавлена возможность указывать каталоги для конкретного загрузчика файловой системы.
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: Распространение приложений в формате egg не рекомендуется.
Точно так же, как
app_directoriesвыше, но он загружает шаблоны из Python egg, а не из файловой системы.Этот загрузчик отключён по умолчанию.
django.template.loaders.cached.Loader
-
class cached.Loader -
По умолчанию (когда
DEBUGравноTrue), система шаблонов читает и компилирует ваши шаблоны каждый раз, когда они отображаются. Хотя система Django шаблонов довольно быстрая, накладные расходы от чтения и компиляции шаблонов могут накапливаться.Вы настраиваете кэшируемый загрузчик шаблонов, передавая список других загрузчиков, которые он должен обернуть. Обернутые загрузчики используются для поиска неизвестных шаблонов при их первом обнаружении. Кэшируемый загрузчик затем сохраняет скомпилированные
Templateв памяти. Экземпляр кэшируемогоTemplateвозвращается для последующих запросов на загрузку того же шаблона.Этот загрузчик автоматически включён, если
OPTIONS['loaders']не указан иOPTIONS['debug']равноFalse(последний параметр по умолчанию равен значениюDEBUG).Вы также можете включить кеширование шаблонов с помощью некоторых пользовательских загрузчиков шаблонов, используя настройки, подобные этим:
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', 'path.to.custom.Loader', ]), ], }, }]Примечание
Все встроенные теги Django шаблонов безопасны для использования с кэшируемым загрузчиком, но если вы используете пользовательские теги шаблонов, полученные из пакетов сторонних производителей или созданные вами, убедитесь, что реализация
Nodeдля каждого тега является потокобезопасной. Дополнительную информацию см. в учитывании потокобезопасности тегов шаблона.Изменено в Django 1.11:Добавлена автоматическая активация кэшируемого загрузчика шаблонов, когда
debugравноFalse.
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().
Методы загрузчика
-
class Loader[source] -
Загружает шаблоны из заданного источника, например, файловой системы или базы данных.
-
get_template_sources(template_name)[source] -
Метод, принимающий
template_nameи возвращающийOriginобъекты для каждого возможного источника.Например, загрузчик файловой системы может получить
'index.html'в качествеtemplate_nameаргумента. Этот метод вернёт объекты, соответствующие полному пути кindex.htmlв каждой папке шаблонов, которую просматривает загрузчик.Методу не нужно проверять, существует ли шаблон по заданному пути, но он должен убедиться, что путь корректен. Например, загрузчик файловой системы проверяет, что путь лежит внутри корректной папки шаблонов.
-
get_contents(origin) -
Возвращает содержимое шаблона для заданного объекта
Origin.Здесь загрузчик файловой системы считывает содержимое из файловой системы, а загрузчик базы данных – из базы данных. Если шаблон по указанному пути не найден, должно быть выброшено исключение
TemplateDoesNotExist.
-
get_template(template_name, skip=None)[source] -
Возвращает объект
Templateдля заданногоtemplate_name, перебирая результаты изget_template_sources()и вызываяget_contents(). Это возвращает первый найденный шаблон. Если шаблон не найден, вызывается исключениеTemplateDoesNotExist.Необязательный аргумент
skip– список объектов, представляющих источники, которые нужно пропустить при расширении шаблонов. Это позволяет шаблонам расширять другие шаблоны с тем же именем. Также это используется для избежания рекурсивных ошибок.В целом, для настраиваемых загрузчиков шаблонов достаточно определить
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 с атрибутами, зависящими от источника их загрузки.
-
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.11/ref/templates/api/