将模板升级到Django 1.8¶
Django模板系统在Django 1.8中进行了大修,当它获得了对多个模板引擎的支持。本文档补充了 发行说明 的一些主题的详细升级说明。
TEMPLATES
设置¶
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
。
如果您的设置模块定义了 ALLOWED_INCLUDE_ROOTS
或 TEMPLATE_STRING_IF_INVALID
,请将其值包含在 'OPTIONS'
字典中的 'allowed_include_roots'
和 'string_if_invalid'
键下。
如果它将 TEMPLATE_DEBUG
设置为与 DEBUG
不同的值,则将该值包括在 'OPTIONS'
中的 'debug'
密钥下。
一旦定义了 TEMPLATES
,您可以安全地删除 ALLOWED_INCLUDE_ROOTS
,TEMPLATE_CONTEXT_PROCESSORS
,TEMPLATE_DEBUG
,TEMPLATE_DIRS
,TEMPLATE_LOADERS
和 TEMPLATE_STRING_IF_INVALID
。
如果您在测试中覆盖某些设置,则应覆盖整个 TEMPLATES
设置。
django.template.loader
¶
get_template()
和 select_template()
¶
在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 1.10中支持。
如果在使用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和更早版本中使用的那样,避免了所有向后兼容性问题。
get_template_from_string()
¶
私有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(template_code)
实例化模板遇到与 get_template_from_string()
相同的问题。
当 TEMPLATES
设置仅定义一个 DjangoTemplates
后端时,它仍然有效,但可插入应用程序无法控制此要求。
在这种情况下,建议在上一节中描述的最后两个解决方案。