TemplateResponseSimpleTemplateResponse

标准的 HttpResponse 对象是静态结构。它们在构造时被提供了一块预渲染的内容,虽然可以修改该内容,但其形式并不易于进行修改。

但是,有时让装饰器或中间件在视图构造响应 *之后* 修改响应可能很有益。例如,您可能希望更改使用的模板,或将其他数据放入上下文。

TemplateResponse 提供了一种方法来做到这一点。与基本的 HttpResponse 对象不同,TemplateResponse 对象保留了视图用来计算响应的模板和上下文的详细信息。响应的最终输出直到响应过程的后期需要时才计算。

SimpleTemplateResponse 对象

class SimpleTemplateResponse[source]

属性

SimpleTemplateResponse.template_name

要渲染的模板的名称。接受依赖于后端的模板对象(例如 get_template() 返回的对象)、模板名称或模板名称列表。

示例:['foo.html', 'path/to/bar.html']

SimpleTemplateResponse.context_data

渲染模板时要使用的上下文数据。它必须是 dict

示例:{'foo': 123}

SimpleTemplateResponse.rendered_content[source]

使用当前模板和上下文数据的响应内容的当前渲染值。

SimpleTemplateResponse.is_rendered[source]

一个布尔值,指示响应内容是否已渲染。

方法

SimpleTemplateResponse.__init__(template, context=None, content_type=None, status=None, charset=None, using=None, headers=None)[source]

使用给定的模板、上下文、内容类型、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

要添加到响应的 HTTP 标头的 dict

SimpleTemplateResponse.resolve_context(context)[source]

预处理将用于渲染模板的上下文数据。接受上下文数据的 dict。默认情况下,返回相同的 dict

为了自定义上下文,请覆盖此方法。

SimpleTemplateResponse.resolve_template(template)[source]

解析要用于渲染的模板实例。接受依赖于后端的模板对象(例如 get_template() 返回的对象)、模板名称或模板名称列表。

返回要渲染的依赖于后端的模板对象实例。

为了自定义模板加载,请覆盖此方法。

SimpleTemplateResponse.add_post_render_callback()[source]

添加一个回调,该回调将在渲染完成后调用。此钩子可用于将某些处理操作(例如缓存)推迟到渲染发生之后。

如果 SimpleTemplateResponse 已被渲染,则将立即调用回调。

调用时,回调将传递一个参数——已渲染的 SimpleTemplateResponse 实例。

如果回调返回的值不是 None,则此值将用作响应,而不是原始响应对象(并将传递给下一个渲染后回调等)。

SimpleTemplateResponse.render()[source]

response.content 设置为通过 SimpleTemplateResponse.rendered_content 获得的结果,运行所有渲染后回调,并返回生成的响应对象。

render() 只会在第一次调用时有效。在后续调用中,它将返回第一次调用获得的结果。

TemplateResponse 对象

class TemplateResponse[source]

TemplateResponseSimpleTemplateResponse 的子类,它了解当前的 HttpRequest

方法

TemplateResponse.__init__(request, template, context=None, content_type=None, status=None, charset=None, using=None, headers=None)[source]

使用给定的请求、模板、上下文、内容类型、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

要添加到响应的 HTTP 标头的 dict

渲染过程

在将 TemplateResponse 实例返回给客户端之前,必须对其进行渲染。渲染过程采用模板和上下文的中间表示,并将其转换为可以提供给客户端的最终字节流。

在以下三种情况下,将渲染 TemplateResponse

  • 当使用 SimpleTemplateResponse.render() 方法显式渲染 TemplateResponse 实例时。

  • 当通过赋值 response.content 显式设置响应内容时。

  • 通过模板响应中间件后,但在通过响应中间件之前。

TemplateResponse 只能渲染一次。第一次调用 SimpleTemplateResponse.render() 会设置响应的内容;后续的渲染调用不会更改响应内容。

但是,当显式赋值 response.content 时,更改始终会被应用。如果要强制重新渲染内容,可以重新评估渲染后的内容,并手动分配响应的内容。

# 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 实例作为参数提供。

如果模板已经渲染,则将立即调用回调。

使用 TemplateResponseSimpleTemplateResponse

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()}
    )
返回顶部