Язык шаблонов Django: для программистов Python
Этот документ объясняет систему шаблонов Django с технической точки зрения — как она работает и как ее расширить. Если вы просто ищете справочную информацию о синтаксисе языка, см. Язык шаблонов Django.
Предполагается понимание шаблонов, контекстов, переменных, тегов и рендеринга. Начните с введения в язык шаблонов Django, если вы не знакомы с этими понятиями.
Обзор
Использование системы шаблонов на Python — это трехэтапный процесс:
- Вы настраиваете
Engine. - Вы компилируете код шаблона в
Template. - Вы рендерите шаблон с помощью
Context.
Проекты Django, как правило, полагаются на API высокого уровня, независимые от бэкэнда для каждого из этих шагов, а не на низкоуровневые API системы шаблонов:
- Для каждого бэкэнда
DjangoTemplatesв настройкеTEMPLATESDjango создает экземпляр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, allowed_include_roots=None, context_processors=None, debug=False, loaders=None, string_if_invalid='', file_charset='utf-8', libraries=None, builtins=None)[source] -
При создании экземпляра
Engineвсе аргументы должны передаваться в виде именованных аргументов:-
dirs— список каталогов, в которых движок должен искать файлы исходного кода шаблонов. Используется для настройкиfilesystem.Loader.По умолчанию пустой список.
-
app_dirsвлияет только на значение по умолчанию дляloaders. См. ниже.По умолчанию
False. -
allowed_include_roots— список строк, представляющих разрешённые префиксы для тега шаблона{% ssi %}. Это мера безопасности, чтобы авторы шаблонов не могли получить доступ к файлам, к которым у них нет доступа.Например, если
'allowed_include_roots'—['/home/html', '/var/www'], то{% ssi /home/html/foo.txt %}будет работать, но{% ssi /etc/passwd %}— нет.По умолчанию пустой список.
Устаревшее с версии 1.8:
allowed_include_rootsустарело. -
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.
См. Типы загрузчиков для получения подробностей.
-
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, current_app=_current_app_undefined)[source] -
Этот класс находится в
django.template.Context. Конструктор принимает два необязательных аргумента:- Словарь, сопоставляющий имена переменных их значениям.
-
Имя текущего приложения. Это имя приложения используется для помощи в разрешении именованных URL-адресов. Если вы не используете именованные URL-адреса, вы можете проигнорировать этот аргумент.
Устарело начиная с версии 1.8: Аргумент
current_appустарел. Если вам он нужен, вы должны теперь использоватьRequestContext, а не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 может быть полезным инструментом отладки, не стоит включать его по умолчанию в режиме разработки.
Многие шаблоны, включая те, что используются на сайте администрирования, полагаются на то, что система шаблонов молчит, когда встречает несуществующую переменную. Если вы назначите значение, отличное от '' параметру 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'
Возможность использования 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',
})
Наследование от Context: 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',
]
Встроенные обработчики контекста шаблонов были перемещены из django.core.context_processors в django.template.context_processors в Django 1.8.
Помимо этих, 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
def ip_address_processor(request):
return {'ip_address': request.META['REMOTE_ADDR']}
def some_view(request):
# ...
c = RequestContext(request, {
'foo': 'bar',
}, [ip_address_processor])
return HttpResponse(t.render(c))
Встроенные обработчики контекста шаблонов
Вот что делает каждый из встроенных обработчиков:
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
Это значение раньше определялось настройкой TEMPLATE_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')], }]
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-пакетов, а не из файловой системы.Этот загрузчик отключён по умолчанию.
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.template.loaders.base.Loader раньше определялся в django.template.loader.BaseLoader.
В предыдущих версиях 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представляет собой список origins, которые необходимо игнорировать при расширении шаблонов. Это позволяет шаблонам расширять другие шаблоны с тем же именем. Также используется для предотвращения рекурсивных ошибок.В целом, для пользовательских загрузчиков шаблонов достаточно определить
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 ранее создавал origin на основе 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.9/ref/templates/api/