Язык шаблонов 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()
метод , который Marshals контекст и , возможно , запрос в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 ) ¶ При создании экземпляра
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
() ¶ Возвращает базовый объект
Engine
из первого настроенногоDjangoTemplates
движка. Повышается,ImproperlyConfigured
если не настроены никакие двигатели.Это необходимо для сохранения API-интерфейсов, которые полагаются на глобально доступный, неявно настроенный движок. Любое другое использование категорически не рекомендуется.
-
Engine.
from_string
( template_code ) ¶ Компилирует указанный код шаблона и возвращает
Template
объект.
-
Engine.
get_template
( имя_шаблона ) ¶ Загружает шаблон с заданным именем, компилирует его и возвращает
Template
объект.
-
Engine.
select_template
( template_name_list ) ¶ Как
get_template()
, за исключением того, что он принимает список имен и возвращает первый найденный шаблон.
Загрузка шаблона ¶
Рекомендуемый способ создания Template
является вызовом фабричных методов из Engine
: get_template()
,
select_template()
и from_string()
.
В проекте Django, где TEMPLATES
параметр определяет
DjangoTemplates
движок, можно Template
напрямую создать экземпляр . Если определено более одного
DjangoTemplates
двигателя, будет использоваться первый.
-
класс
Template
¶ Этот класс живет по адресу
django.template.Template
. Конструктор принимает один аргумент - исходный код шаблона:from django.template import Template template = Template("My name is {{ my_name }}.")
За кулисами
Система анализирует исходный код шаблона только один раз - при создании
Template
объекта. С этого момента он хранится внутри как древовидная структура для повышения производительности.
Даже сам парсинг довольно быстрый. Большая часть синтаксического анализа происходит с помощью одного вызова одного короткого регулярного выражения.
Визуализация контекста ¶
Когда у вас есть скомпилированный Template
объект, вы можете визуализировать с ним контекст. Вы можете повторно использовать один и тот же шаблон, чтобы отображать его несколько раз в разных контекстах.
-
class
Context
( dict_ = None ) ¶ Конструктор
django.template.Context
принимает необязательный аргумент - словарь, сопоставляющий имена переменных со значениями переменных.Дополнительные сведения см. В разделе « Игра с объектами контекста» ниже.
-
Template.
render
( контекст ) ¶ Вызовите метод
Template
объектаrender()
с помощью,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."
Переменные и поиск ¶
Имена переменных должны состоять из любой буквы (AZ), любой цифры (0–9), символа подчеркивания (но они не должны начинаться с подчеркивания) или точки.
Точки имеют особое значение при отрисовке шаблона. Точка в имени переменной означает поиск . В частности, когда система шаблонов встречает точку в имени переменной, она пытается выполнить следующие поиски в следующем порядке:
- Поиск по словарю. Пример:
foo["bar"]
- Поиск по атрибутам. Пример:
foo.bar
- Поиск по списку-индексу. Пример:
foo[bar]
Обратите внимание, что «bar» в выражении шаблона, например, будет интерпретироваться как буквальная строка и не будет использовать значение переменной «bar», если она существует в контексте шаблона.{{ foo.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
, что это базовый класс для всехDoesNotExist
исключений API базы данных Django . Так что, если вы используете шаблоны Django с объектами модели Django, любое исключение не сработает.silent_variable_failure = True
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
для следующих выражений будет повышен a :
{% 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
ifkey
в контексте, else возвращаетotherwise
.
-
Context.
setdefault
( ключ , по умолчанию = Нет ) ¶ Если
key
находится в контексте, возвращает его значение. В противном случае вставляетkey
значениеdefault
и возвращаетdefault
.
-
Context.
pop
() ¶
-
Context.
push
() ¶
-
исключение
ContextPopException
¶
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 ) ¶
В дополнение к 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'
Использование a 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
( запрос , dict_ = None , processors = None ) ¶
В 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
() ¶
Если этот процессор включен, каждый RequestContext
будет содержать следующие переменные:
user
-auth.User
Экземпляр, представляющий текущего вошедшего в систему пользователя (илиAnonymousUser
экземпляр, если клиент не вошел в систему).perms
- Экземплярdjango.contrib.auth.context_processors.PermWrapper
, представляющий разрешения, которые есть у текущего вошедшего в систему пользователя.
django.template.context_processors.debug
¶
-
debug
() ¶
Если этот процессор включен, каждый RequestContext
будет содержать эти две переменные, но только если ваш DEBUG
параметр установлен на True
и IP-адрес запроса ( request.META['REMOTE_ADDR']
) находится в
INTERNAL_IPS
настройке:
debug
-True
. Вы можете использовать это в шаблонах, чтобы проверить, находитесь ли вы вDEBUG
режиме.sql_queries
- Список словарей, представляющих все SQL-запросы, которые были выполнены во время запроса, и сколько времени это заняло. Список отсортирован по псевдониму базы данных, а затем по запросу. Он лениво генерируется при доступе.{'sql': ..., 'time': ...}
django.template.context_processors.i18n
¶
-
i18n
() ¶
Если этот процессор включен, каждый 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
() ¶
Если этот процессор включен, каждый 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
() ¶
Если этот процессор включен, каждый RequestContext
будет содержать переменную
TIME_ZONE
, предоставляющую имя текущего активного часового пояса.
django.contrib.messages.context_processors.messages
¶
Если этот процессор включен, каждый RequestContext
будет содержать эти две переменные:
messages
- Список сообщений (в виде строк), которые были установлены через структуру сообщений .DEFAULT_MESSAGE_LEVELS
- Отображение имен уровней сообщений их числовым значениям .
Написание собственных контекстных процессоров ¶
У обработчика контекста простой интерфейс: это функция Python, которая принимает один аргумент, HttpRequest
объект, и возвращает словарь, который добавляется в контекст шаблона.
Например, чтобы добавить DEFAULT_FROM_EMAIL
параметр в каждый контекст:
from django.conf import settings
def from_email(request):
return {
"DEFAULT_FROM_EMAIL": settings.DEFAULT_FROM_EMAIL,
}
Пользовательские процессоры контекста могут находиться где угодно в вашей кодовой базе. Все, о чем заботится Django, - это то, что на ваши пользовательские процессоры контекста указывает
'context_processors'
параметр в ваших TEMPLATES
настройках - или
context_processors
аргумент, Engine
если вы используете его напрямую.
Загрузка шаблонов ¶
Как правило, вы будете хранить шаблоны в файлах в своей файловой системе, а не использовать низкоуровневый Template
API самостоятельно. Сохраняйте шаблоны в каталоге, указанном как каталог шаблонов .
Django ищет каталоги шаблонов в нескольких местах, в зависимости от ваших настроек загрузки шаблона (см. «Типы загрузчиков» ниже), но самый простой способ указать каталоги шаблонов - использовать эту DIRS
опцию.
DIRS
Вариант ¶
Сообщите Django, какие у вас каталоги шаблонов, используя DIRS
опцию в TEMPLATES
настройках вашего файла настроек или dirs
аргумент Engine
. Это должен быть список строк, содержащих полные пути к вашим каталогам шаблонов:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
'/home/html/templates/lawrence.com',
'/home/html/templates/default',
],
},
]
Ваши шаблоны могут располагаться где угодно, если каталоги и шаблоны доступны для чтения веб-серверу. У них может быть любое расширение, например .html
или .txt
, или вообще не может быть расширения.
Обратите внимание, что эти пути должны использовать косую черту в стиле Unix даже в Windows.
Типы загрузчиков ¶
По умолчанию Django использует загрузчик шаблонов на основе файловой системы, но Django поставляется с несколькими другими загрузчиками шаблонов, которые знают, как загружать шаблоны из других источников.
Некоторые из этих загрузчиков отключены по умолчанию, но вы можете активировать их, добавив 'loaders'
параметр в свой DjangoTemplates
сервер в
TEMPLATES
настройках или передав loaders
аргумент в
Engine
. loaders
должен быть списком строк или кортежей, каждый из которых представляет класс загрузчика шаблона. Вот загрузчики шаблонов, которые поставляются с Django:
django.template.loaders.filesystem.Loader
-
класс
filesystem.
Loader
¶ Загружает шаблоны из файловой системы в соответствии с
DIRS
.Этот загрузчик включен по умолчанию. Однако он не найдет никаких шаблонов, пока вы не установите
DIRS
непустой список:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], }]
Вы также можете переопределить
'DIRS'
и указать определенные каталоги для определенного загрузчика файловой системы:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'OPTIONS': { 'loaders': [ ( 'django.template.loaders.filesystem.Loader', [BASE_DIR / 'templates'], ), ], }, }]
django.template.loaders.app_directories.Loader
-
класс
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
«s будет загружен первый и ваш будет игнорироваться.Обратите внимание, что загрузчик выполняет оптимизацию при первом запуске: он кэширует список
INSTALLED_APPS
пакетов, имеющихtemplates
подкаталог.Вы можете включить этот загрузчик, установив
APP_DIRS
наTrue
:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'APP_DIRS': True, }]
django.template.loaders.cached.Loader
-
класс
cached.
Loader
¶ По умолчанию (когда
DEBUG
естьTrue
) система шаблонов считывает и компилирует ваши шаблоны каждый раз, когда они отображаются. Хотя система шаблонов Django работает довольно быстро, накладные расходы на чтение и компиляцию шаблонов могут возрасти.Вы настраиваете кэшированный загрузчик шаблонов со списком других загрузчиков, которые он должен обернуть. Упакованные загрузчики используются для поиска неизвестных шаблонов при первом их обнаружении. Затем кешированный загрузчик сохраняет скомпилированный файл
Template
в памяти. КешированныйTemplate
экземпляр возвращается для последующих запросов на загрузку того же шаблона.Этот загрузчик автоматически включается , если
OPTIONS['loaders']
не указан иOPTIONS['debug']
являетсяFalse
(последним вариантом по умолчанию значенияDEBUG
).Вы также можете включить кэширование шаблонов с помощью некоторых пользовательских загрузчиков шаблонов, используя следующие параметры:
TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [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
-
класс
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()
методы.
Методы загрузчика ¶
-
класс
Loader
¶ Загружает шаблоны из заданного источника, такого как файловая система или база данных.
-
get_template_sources
( имя_шаблона ) ¶ Метод, который принимает
template_name
и выдаетOrigin
экземпляры для каждого возможного источника.Например, загрузчик файловой системы может получить
'index.html'
в качествеtemplate_name
аргумента. Этот метод даст исходные данные для полного пути,index.html
который отображается в каждом каталоге шаблонов, на который смотрит загрузчик.Этому методу не нужно проверять, существует ли шаблон по заданному пути, но он должен гарантировать, что путь действителен. Например, загрузчик файловой системы следит за тем, чтобы путь лежал в допустимом каталоге шаблона.
-
get_contents
( происхождение ) ¶ Возвращает содержимое шаблона для данного
Origin
экземпляра.Здесь загрузчик файловой системы будет читать содержимое из файловой системы или загрузчик базы данных будет читать из базы данных. Если соответствующий шаблон не существует, это должно вызвать
TemplateDoesNotExist
ошибку.
-
get_template
( template_name , skip = None ) ¶ Возвращает
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 ) ¶ -
name
¶ Путь к шаблону, возвращенный загрузчиком шаблона. Для загрузчиков, которые читают из файловой системы, это полный путь к шаблону.
Если шаблон создается напрямую, а не через загрузчик шаблона, это строковое значение
<unknown_source>
.
-
template_name
¶ Относительный путь к шаблону, переданный в загрузчик шаблона.
Если шаблон создается напрямую, а не через загрузчик шаблонов, то это так
None
.
-
loader
¶ Экземпляр загрузчика шаблонов, создавший this
Origin
.Если шаблон создается напрямую, а не через загрузчик шаблонов, то это так
None
.django.template.loaders.cached.Loader
требует, чтобы все его упакованные загрузчики установили этот атрибут, обычно путем создания экземпляраOrigin
сloader=self
.
-