Язык шаблонов Django: для программистов Python
Этот документ объясняет систему шаблонов Django с технической точки зрения — как она работает и как ее расширить. Если вы просто ищете справочник по синтаксису языка, см. Язык шаблонов Django.
Предполагается понимание шаблонов, контекстов, переменных, тегов и рендеринга. Начните с введения в язык шаблонов Django, если вы не знакомы с этими понятиями.
Обзор
Использование системы шаблонов на Python — это трехэтапный процесс:
- Вы настраиваете
Engine. - Вы компилируете код шаблона в
Template. - Вы рендерите шаблон с помощью
Context.
Проекты Django, как правило, полагаются на высокоуровневые, независимые от бэкенда API для каждого из этих шагов вместо низкоуровневых API системы шаблонов:
- Для каждого
DjangoTemplatesбэкенда в настройкеTEMPLATES, Django инициализируетEngine.DjangoTemplatesоборачиваетEngineи адаптирует его к общему API бэкенда шаблонов. - Модуль
django.template.loaderпредоставляет функции, такие какget_template()для загрузки шаблонов. Они возвращаютdjango.template.Template. - Полученный на предыдущем шаге
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')[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'.
-
-
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.
Подробности см. в разделе Работа с объектами контекста ниже.
-
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's шаблонный анализатор ищет первое вхождение %} после {%. Это предотвращает использование "%}" как строковой литерал. Например, возникнет 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.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'
Использование 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.contrib.messages.context_processors.messages
Если этот обработчик включён, каждый RequestContext будет содержать эти две переменные:
-
messages– Список сообщений (как строки), которые были установлены с помощью фреймворка сообщений. -
DEFAULT_MESSAGE_LEVELS– Сопоставление имён уровней сообщений с их числовым значением.
Переменная 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, или вообще не иметь расширения.
Обратите внимание, что эти пути должны использовать косые черты (/) в стиле Unix, даже в Windows.
Типы загрузчиков
По умолчанию Django использует загрузчик шаблонов на основе файловой системы, но Django поставляется с несколькими другими загрузчиками шаблонов, которые знают, как загружать шаблоны из других источников.
Некоторые из этих загрузчиков по умолчанию отключены, но вы можете активировать их, добавив опцию 'loaders' к вашему бэкенду DjangoTemplates в настройке TEMPLATES или передав аргумент loaders в Engine. loaders должен быть списком строк или кортежей, где каждый элемент представляет класс загрузчика шаблонов. Вот загрузчики шаблонов, которые поставляются с Django:
django.template.loaders.filesystem.Loader
-
class filesystem.Loader -
Загружает шаблоны из файловой системы в соответствии с
DIRS.Этот загрузчик включён по умолчанию. Однако он не найдёт шаблоны, пока вы не установите
DIRSв список, отличный от пустого:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], }]
django.template.loaders.app_directories.Loader
-
class app_directories.Loader -
Загружает шаблоны из приложений Django из файловой системы. Для каждого приложения в
INSTALLED_APPSзагрузчик ищет подкаталогtemplates. Если каталог существует, Django ищет шаблоны там.Это означает, что вы можете хранить шаблоны вместе со своими отдельными приложениями. Это также упрощает распространение приложений Django с шаблонами по умолчанию.
Например, для такой настройки:
INSTALLED_APPS = ('myproject.polls', 'myproject.music')...тогда
get_template('foo.html')будет искатьfoo.htmlв этих каталогах в указанном порядке:/path/to/myproject/polls/templates//path/to/myproject/music/templates/
... и будет использовать первый найденный.
Порядок следования в
INSTALLED_APPSважен! Например, если вы хотите настроить Django админ-панель, вы можете переопределить стандартный шаблонadmin/base_site.htmlизdjango.contrib.adminсвоим собственнымadmin/base_site.htmlвmyproject.polls. Затем убедитесь, что ваше приложениеmyproject.pollsрасположено передdjango.contrib.adminвINSTALLED_APPS, иначе шаблоныdjango.contrib.adminбудут загружены первыми, и ваши будут проигнорированы.Обратите внимание, что загрузчик выполняет оптимизацию при первом запуске: кеширует список пакетов
INSTALLED_APPS, содержащих подкаталогtemplates.Вы можете включить этот загрузчик, просто установив
APP_DIRSвTrue:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'APP_DIRS': True, }]
django.template.loaders.eggs.Loader
-
class eggs.Loader -
Точно так же, как и
app_directoriesвыше, но загружает шаблоны из Python eggs, а не из файловой системы.Этот загрузчик отключен по умолчанию.
django.template.loaders.cached.Loader
-
class cached.Loader -
По умолчанию система шаблонизации будет читать и компилировать ваши шаблоны каждый раз, когда они должны быть рендерированы. Хотя система шаблонизации Django довольно быстрая, накладные расходы от чтения и компиляции шаблонов могут накапливаться.
Кешированный загрузчик шаблонов — это загрузчик на основе класса, который вы настраиваете с помощью списка других загрузчиков, которые он должен обернуть. Обернутые загрузчики используются для поиска неизвестных шаблонов, когда они встречаются впервые. Затем кешированный загрузчик сохраняет скомпилированные
Templateв памяти. ЭкземплярTemplateвозвращается для последующих запросов на загрузку того же шаблона.Например, чтобы включить кэширование шаблонов с загрузчиками шаблонов
filesystemиapp_directories, вы можете использовать следующие настройки:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'OPTIONS': { 'loaders': [ ('django.template.loaders.cached.Loader', [ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', ]), ], }, }]Примечание
Все встроенные теги Django шаблонов безопасны для использования с кэшированным загрузчиком, но если вы используете пользовательские теги шаблонов из сторонних пакетов или написанные вами, вы должны убедиться, что реализация
Nodeдля каждого тега потокобезопасна. Для получения дополнительной информации см. учёт потоковой безопасности тега шаблона.Этот загрузчик отключён по умолчанию.
django.template.loaders.locmem.Loader
-
class locmem.Loader -
Загружает шаблоны из словаря Python. Это полезно для тестирования.
Этот загрузчик принимает словарь шаблонов в качестве первого аргумента:
TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'OPTIONS': { 'loaders': [ ('django.template.loaders.locmem.Loader', { 'index.html': 'content here', }), ], }, }]Этот загрузчик отключён по умолчанию.
Django использует загрузчики шаблонов в порядке, указанном в опции 'loaders'. Он использует каждый загрузчик до тех пор, пока загрузчик не найдёт соответствие.
Пользовательские загрузчики
Пользовательские классы Loader должны наследоваться от django.template.loaders.base.Loader и переопределять метод load_template_source(), который принимает аргумент template_name, загружает шаблон из файла (или из другого места) и возвращает кортеж: (template_string, template_origin).
django.template.loaders.base.Loader ранее определялся в django.template.loader.BaseLoader.
Метод load_template() класса Loader извлекает строку шаблона, вызывая load_template_source(), создаёт экземпляр Template из исходного кода шаблона и возвращает кортеж: (template, template_origin).
Происхождение шаблона
Когда Engine инициализируется с debug=True, его шаблоны имеют атрибут origin, зависящий от источника, из которого они загружаются. Для движков, инициализированных Django, debug по умолчанию имеет значение DEBUG.
-
class loader.LoaderOrigin -
Шаблоны, созданные из загрузчика шаблонов, будут использовать класс
django.template.loader.LoaderOrigin.-
name -
Путь к шаблону, возвращаемый загрузчиком шаблонов. Для загрузчиков, которые читают из файловой системы, это полный путь к шаблону.
-
loadname -
Относительный путь к шаблону, переданный в загрузчик шаблонов.
-
-
class StringOrigin[source] -
Шаблоны, созданные из класса
Template, будут использовать классdjango.template.StringOrigin.-
source -
Строка, используемая для создания шаблона.
-
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.8/ref/templates/api/