Язык шаблонов 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-шаблоны! -
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.См. Типы загрузчиков для получения подробной информации.
-
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 %}.
-
-
static Engine.get_default()[source] -
Возвращает базовый
Engineиз первого настроенногоDjangoTemplatesдвижка. Вызывает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. Если определено более одного движка DjangoTemplates, будет использован первый.
-
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 базы данных 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 может быть полезным инструментом отладки, не рекомендуется включать его в качестве значения по умолчанию для разработки.
Многие шаблоны, включая некоторые шаблоны Django, полагаются на молчание системы шаблонов при столкновении с несуществующей переменной. Если вы назначите значение, отличное от '' для 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) -
Если
keyнаходится в контексте, возвращает его значение. В противном случае вставляетkeyсо значениемdefaultи возвращаетdefault.
-
Context.pop()
-
Context.push()
-
exception ContextPopException[source]
Объект Context является стеком. То есть, вы можете push() и 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'
Использование 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
-
i18n()[source]
Если этот обработчик включен, каждый RequestContext будет содержать эти переменные:
-
LANGUAGES– Значение параметраLANGUAGES. -
LANGUAGE_BIDI–True, если текущий язык — язык справа налево, например, иврит, арабский.False, если это язык слева направо, например, английский, французский, немецкий. -
LANGUAGE_CODE–request.LANGUAGE_CODE, если он существует. В противном случае значение параметраLANGUAGE_CODE.
См. теги шаблонов i18n для тегов шаблонов, которые генерируют те же значения.
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, или не иметь его вовсе.
Обратите внимание, что эти пути должны использовать косые черты, даже в 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.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.cached.Loader
-
class cached.Loader -
По умолчанию (когда
DEBUGравенTrue), система шаблонов читает и компилирует ваши шаблоны каждый раз, когда они отрисовываются. Хотя система шаблонов Django довольно быстрая, накладные расходы от чтения и компиляции шаблонов могут накапливаться.Вы настраиваете загрузчик шаблонов с кешем, используя список других загрузчиков, которые он должен обернуть. Обёрнутые загрузчики используются для поиска неизвестных шаблонов, когда они встречаются впервые. Загрузчик с кешем затем сохраняет скомпилированные
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.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()обычно переопределять не нужно.
-
Разработка собственного
Примеры можно найти в исходном коде встроенных загрузчиков Django.
Происхождение шаблона
Шаблоны имеют origin, содержащие атрибуты, зависящие от источника, из которого они загружены.
-
class Origin(name, template_name=None, loader=None)[source] -
-
name -
Путь к шаблону, возвращаемый загрузчиком шаблонов. Для загрузчиков, которые считывают из файловой системы, это полный путь к шаблону.
Если шаблон инициализирован непосредственно, а не через загрузчик шаблонов, это строковое значение
<unknown_source>.
-
template_name -
Относительный путь к шаблону, переданный загрузчику шаблонов.
Если шаблон инициализирован непосредственно, а не через загрузчик шаблонов, это
None.
-
loader -
Экземпляр загрузчика шаблонов, который создал этот
Origin.Если шаблон инициализирован непосредственно, а не через загрузчик шаблонов, это
None.django.template.loaders.cached.Loaderтребует, чтобы все его обернутые загрузчики устанавливали этот атрибут, обычно инициализируяOriginсloader=self.
-
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/2.2/ref/templates/api/