当Django 1.8获得对多个模板引擎的支持时,Django的模板系统被大修。本文档补充了release notes以及有关某些主题的详细升级说明。
Django 1.8中引入了一项新设置:TEMPLATES。所有现有的模板相关设置已弃用。
在弃用期间,如果您不自行定义,Django将根据TEMPLATE_*设置创建向后兼容的TEMPLATES。
以下说明如何在设置模块中定义TEMPLATES。
如果您使用的默认值为TEMPLATE_LOADERS,也就是说,如果未在设置文件中定义或设置为:
('django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader')
则应定义TEMPLATES,如下所示:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
# insert your TEMPLATE_DIRS here
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
# Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
# list if you haven't customized them:
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
},
},
]
如果您未使用默认值TEMPLATE_LOADERS,则应定义TEMPLATES,如下所示:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
# insert your TEMPLATE_DIRS here
],
'OPTIONS': {
'context_processors': [
# Insert your TEMPLATE_CONTEXT_PROCESSORS here or use this
# list if you haven't customized them:
'django.contrib.auth.context_processors.auth',
'django.template.context_processors.debug',
'django.template.context_processors.i18n',
'django.template.context_processors.media',
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
],
'loaders': [
# insert your TEMPLATE_LOADERS here
]
},
},
]
此外,您应该在上下文处理器的名称中将django.core.context_processors替换为django.template.context_processors。
If your settings module defines ALLOWED_INCLUDE_ROOTS or TEMPLATE_STRING_IF_INVALID, include their values under the 'allowed_include_roots' and 'string_if_invalid' keys in the 'OPTIONS' dictionary.
If it sets TEMPLATE_DEBUG to a value that differs from DEBUG, include that value under the 'debug' key in 'OPTIONS'.
Once you have defined TEMPLATES, you can safely remove ALLOWED_INCLUDE_ROOTS, TEMPLATE_CONTEXT_PROCESSORS, TEMPLATE_DEBUG, TEMPLATE_DIRS, TEMPLATE_LOADERS, and TEMPLATE_STRING_IF_INVALID.
如果您在测试中覆写某些设置,则应改为覆盖整个TEMPLATES设置。
在Django 1.8 get_template()和select_template()返回一个后端依赖的Template,而不是django.template.Template
例如,如果get_template()加载了具有DjangoTemplates后端的模板,则会返回django.template.backends.django.Template。
Template对象必须提供render()方法,其签名与Django模板语言的render()稍有不同。
代替:
from django.template import Context
from django.template.loader import get_template
template = get_template('hello.html')
html = template.render(Context({'name': 'world'}))
你应该写:
from django.template.loader import get_template
template = get_template('hello.html')
html = template.render({'name': 'world'})
而不是:
from django.template import RequestContext
from django.template.loader import get_template
template = get_template('hello.html')
html = template.render(RequestContext(request, {'name': 'world'}))
你应该写:
from django.template.loader import get_template
template = get_template('hello.html')
html = template.render({'name': 'world'}, request)
当模板由DjangoTemplates后端加载时,仍然可以传递Context或RequestContext,但它已被弃用,并且不会在Django中支持2.0。
如果您在使用Django模板语言呈现另一个模板并且可以访问当前上下文(例如在模板标记的render()方法中)时加载模板,则可以直接使用当前Engine。代替:
from django.template.loader import get_template
template = get_template('included.html')
你可以写:
template = context.template.engine.get_template('included.html')
这将加载模板与当前引擎,而不触发多个模板引擎机械,这通常是所需的行为。与以前的解决方案不同,这会返回一个django.template.Template,如get_template(),用于Django 1.7和更早版本,避免所有向后兼容性问题。
私人API get_template_from_string(template_code)在Django 1.8中被删除,因为它没有办法选择引擎来编译模板。
有三种选择。
如果您控制项目的设置,您可以使用配置的引擎之一:
from django.template import engines
template = engines['django'].from_string(template_code)
这会返回依赖于后端的Template对象。
对于不需要上下文处理器或其他任何事情的琐碎模板,您可以创建一个裸机引擎并使用from_string()方法:
from django.template import Engine
template = Engine().from_string(template_code)
这会返回django.template.Template,因为Engine是Django模板语言的API的一部分。这里不涉及多个模板引擎机械。
最后,如果您可以访问当前上下文,您可以使用与上述相同的技巧:
template = context.template.engine.from_string(template_code)
在较小程度上,使用Template(template_code)实例化模板遇到与get_template_from_string()相同的问题。
当TEMPLATES设置仅定义一个DjangoTemplates后端时,它仍然有效,但可插拔应用程序无法控制此要求。
在这种情况下,建议在上一节中描述的最后两个解决方案。
2015年5月13日