TemplateResponse
和 SimpleTemplateResponse
标准 HttpResponse
对象是静态结构。它们在构建时提供了一个预渲染的内容块,虽然这些内容可以修改,但它的形式并不便于进行修改。
然而,有时允许装饰者或中间件在视图构建响应后修改响应可能是有益的。例如,你可能想改变所使用的模板,或者在上下文中放入额外的数据。
TemplateResponse 提供了一种方法来实现这一点。与基本的 HttpResponse
对象不同,TemplateResponse 对象保留了模板和上下文的细节,这些细节是由视图提供的,用于计算响应。响应的最终输出直到需要时才会计算,在响应过程的后面。
SimpleTemplateResponse
对象
属性
-
SimpleTemplateResponse.
template_name
要渲染的模板的名称。接受一个依赖于后台的模板对象(如
get_template()
返回的模板对象)、一个模板的名称或一个模板名称列表。例如:
['foo.html', 'path/to/bar.html']
-
SimpleTemplateResponse.
context_data
渲染模板时要使用的上下文数据,必须是
dict
。例如:
{'foo': 123}
方法
-
SimpleTemplateResponse.
__init__
(template, context=None, content_type=None, status=None, charset=None, using=None, headers=None) 用给定的模板、上下文、内容类型、HTTP 状态和字符集实例化一个
SimpleTemplateResponse
对象。template
- 依赖于后台的模板对象(如
get_template()
返回的模板对象),模板的名称,或者模板名称的列表。 context
- 一个
dict
的值,用于添加到模板上下文中。默认情况下,这是一个空字典。 content_type
- 包含在 HTTP
Content-Type
头中的值,包括 MIME 类型规格和字符集编码。如果指定了content_type
,则使用其值。否则,使用'text/html'
。 status
- 响应的 HTTP 状态码。
charset
- 响应将被编码的字符集。如果没有给定,将从
content_type
中提取,如果不成功,将使用DEFAULT_CHARSET
设置。 using
- 用于加载模板的模板引擎的
NAME
。 headers
- A
dict
of HTTP headers to add to the response.
-
SimpleTemplateResponse.
resolve_context
(context) 预处理将用于渲染模板的上下文数据。接受一个
dict
的上下文数据。默认情况下,返回相同的dict
。覆盖此方法,以自定义上下文。
-
SimpleTemplateResponse.
resolve_template
(template) 解析用于渲染的模板实例。接受一个依赖于后台的模板对象(例如
get_template()
返回的对象),模板的名称,或者模板名称的列表。返回要渲染的依赖于后台的模板对象实例。
覆盖此方法,以便自定义模板加载。
-
SimpleTemplateResponse.
add_post_render_callback
() 添加一个回调,将在渲染发生后被调用。该钩子可用于将某些处理操作(如缓存)推迟到渲染发生后。
如果
SimpleTemplateResponse
已经被渲染,回调将被立即调用。当调用时,回调将被传递一个单一的参数——渲染的
SimpleTemplateResponse
实例。如果回调返回一个不是
None
的值,这个值将被用作响应,而不是原来的响应对象(并将传递给下一个渲染后回调等)。
-
SimpleTemplateResponse.
render
() 将
response.content
设置为由SimpleTemplateResponse.rendered_content
得到的结果,运行所有的渲染后回调,并返回结果的响应对象。render()
只有在第一次被调用时才会产生效果。在以后的调用中,它将返回第一次调用的结果。
TemplateResponse
对象
-
class
TemplateResponse
TemplateResponse
是SimpleTemplateResponse
的一个子类,它知道当前的HttpRequest
。
方法
-
TemplateResponse.
__init__
(request, template, context=None, content_type=None, status=None, charset=None, using=None, headers=None) 用给定的请求、模板、上下文、内容类型、HTTP 状态和字符集实例化一个
TemplateResponse
对象。request
- 一个
HttpRequest
实例。 template
- 依赖于后台的模板对象(如
get_template()
返回的模板对象),模板的名称,或者模板名称的列表。 context
- 一个
dict
的值,用于添加到模板上下文中。默认情况下,这是一个空字典。 content_type
- 包含在 HTTP
Content-Type
头中的值,包括 MIME 类型规格和字符集编码。如果指定了content_type
,则使用其值。否则,使用'text/html'
。 status
- 响应的 HTTP 状态码。
charset
- 响应将被编码的字符集。如果没有给定,将从
content_type
中提取,如果不成功,将使用DEFAULT_CHARSET
设置。 using
- 用于加载模板的模板引擎的
NAME
。 headers
- A
dict
of HTTP headers to add to the response.
渲染过程
在将 TemplateResponse
实例返回给客户端之前,必须对其进行渲染。渲染过程将模板和上下文的中间表示方式,变成最终的字节流,可以提供给客户端。
在三种情况下,会出现 TemplateResponse
被渲染:
- 当使用
SimpleTemplateResponse.render()
方法显式渲染TemplateResponse
实例时。 - 当通过指定
response.content
明确设置响应的内容时。 - 通过模板响应中间件后,但在通过响应中间件之前。
一个 TemplateResponse
只能被渲染一次。第一次调用 SimpleTemplateResponse.render()
时,会设置响应的内容;后续的渲染调用不会改变响应内容。
However, when response.content
is explicitly assigned, the
change is always applied. If you want to force the content to be
re-rendered, you can reevaluate the rendered content, and assign
the content of the response manually:
# Set up a rendered TemplateResponse
>>> from django.template.response import TemplateResponse
>>> t = TemplateResponse(request, 'original.html', {})
>>> t.render()
>>> print(t.content)
Original content
# Re-rendering doesn't change content
>>> t.template_name = 'new.html'
>>> t.render()
>>> print(t.content)
Original content
# Assigning content does change, no render() call required
>>> t.content = t.rendered_content
>>> print(t.content)
New content
渲染后回调
有些操作——例如缓存——不能在未渲染的模板上执行。它们必须在一个完全完整的、已渲染的响应上执行。
如果你使用的是中间件,你可以这样做。中间件提供了多种机会来处理从视图退出时的响应。如果你把行为放在响应中间件中,就会保证在模板渲染发生后执行。
然而,如果你使用的是一个装饰器,则不存在同样的机会。任何在装饰器中定义的行为都会被立即处理。
为了弥补这一点(以及任何其他类似的用例), TemplateResponse
允许你注册回调,当渲染完成后,这些回调将被调用。使用这个回调,你可以将关键的处理推迟到可以保证渲染内容可用的时候。
要定义一个渲染后的回调,定义一个接受一个参数 response 的函数,然后用模板响应注册该函数:
from django.template.response import TemplateResponse
def my_render_callback(response):
# Do content-sensitive processing
do_post_processing()
def my_view(request):
# Create a response
response = TemplateResponse(request, 'mytemplate.html', {})
# Register the callback
response.add_post_render_callback(my_render_callback)
# Return the response
return response
my_render_callback()
将在 mytemplate.html
被渲染后被调用,并将提供完全渲染的 TemplateResponse
实例作为参数。
如果模板已经被渲染,回调将被立即调用。
使用 TemplateResponse
和 SimpleTemplateResponse
一个 TemplateResponse
对象可以被用于任何可以使用普通 django.http.HttpResponse
的地方。它也可以作为调用 render()
的替代。
例如,下面的视图返回一个 TemplateResponse
,其中有一个模板和一个包含查询集的上下文:
from django.template.response import TemplateResponse
def blog_index(request):
return TemplateResponse(request, 'entry_list.html', {'entries': Entry.objects.all()})
讨论区