# Django 5.2.8 documentation

# `TemplateResponse` 和 `SimpleTemplateResponse`

标准 `HttpResponse` 对象是静态结构。它们在构建时提供了一个预渲染的内容块，虽然这些内容可以修改，但它的形式并不便于进行修改。

然而，有时允许装饰者或中间件在视图构建响应后修改响应可能是有益的。例如，你可能想改变所使用的模板，或者在上下文中放入额外的数据。

TemplateResponse 提供了一种方法来实现这一点。与基本的 `HttpResponse` 对象不同，TemplateResponse 对象保留了模板和上下文的细节，这些细节是由视图提供的，用于计算响应。响应的最终输出直到需要时才会计算，在响应过程的后面。

## `SimpleTemplateResponse` 对象

class SimpleTemplateResponse

### 属性

SimpleTemplateResponse.template_name

  The name of the template to be rendered. Accepts a backend-dependent template object (such as those returned by `get_template()`), the name of a template, or a list of template names.

  例如： `['foo.html', 'path/to/bar.html']`

SimpleTemplateResponse.context_data

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

  例如： `{'foo': 123}`

SimpleTemplateResponse.rendered_content

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

SimpleTemplateResponse.is_rendered

  表示响应内容是否已呈现的布尔值。

### 方法

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

  用给定的模板、上下文、内容类型、HTTP 状态和字符集实例化一个 `SimpleTemplateResponse` 对象。

  `template`

    A backend-dependent template object (such as those returned by `get_template()`), the name of a template, or a list of template names.

  `context`

    一个 `dict` 的值，用于添加到模板上下文中。默认情况下，这是一个空字典。

  `content_type`

    包含在 HTTP `Content-Type` 头中的值，包括 MIME 类型规格和字符集编码。如果指定了 `content_type`，则使用其值。否则，使用 `'text/html'`。

  `status`

    响应的 HTTP 状态码。

  `charset`

    响应将被编码的字符集。如果没有给定，将从 `content_type` 中提取，如果不成功，将使用 `DEFAULT_CHARSET` 设置。

  `using`

    用于加载模板的模板引擎的 `NAME` 。

  `headers`

    一个 `dict` 类型的 HTTP 头信息，用于添加到响应中。

SimpleTemplateResponse.resolve_context(context)

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

  覆盖此方法，以自定义上下文。

SimpleTemplateResponse.resolve_template(template)

  Resolves the template instance to use for rendering. Accepts a backend-dependent template object (such as those returned by `get_template()`), the name of a template, or a list of template names.

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

  覆盖此方法，以便自定义模板加载。

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`

    A backend-dependent template object (such as those returned by `get_template()`), the name of a template, or a list of template names.

  `context`

    一个 `dict` 的值，用于添加到模板上下文中。默认情况下，这是一个空字典。

  `content_type`

    包含在 HTTP `Content-Type` 头中的值，包括 MIME 类型规格和字符集编码。如果指定了 `content_type`，则使用其值。否则，使用 `'text/html'`。

  `status`

    响应的 HTTP 状态码。

  `charset`

    响应将被编码的字符集。如果没有给定，将从 `content_type` 中提取，如果不成功，将使用 `DEFAULT_CHARSET` 设置。

  `using`

    用于加载模板的模板引擎的 `NAME` 。

  `headers`

    一个 `dict` 类型的 HTTP 头信息，用于添加到响应中。

## 渲染过程

在将 `TemplateResponse` 实例返回给客户端之前，必须对其进行渲染。渲染过程将模板和上下文的中间表示方式，变成最终的字节流，可以提供给客户端。

在三种情况下，会出现 `TemplateResponse` 被渲染：

- When the `TemplateResponse` instance is explicitly rendered, using the `SimpleTemplateResponse.render()` method.

- 当通过指定 `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` 实例作为参数。

如果模板已经被渲染，回调将被立即调用。

## 使用 `TemplateResponse` 和 `SimpleTemplateResponse`

A `TemplateResponse` object can be used anywhere that a normal `django.http.HttpResponse` can be used. It can also be used as an alternative to calling `render()`.

例如，下面的视图返回一个 `TemplateResponse`，其中有一个模板和一个包含查询集的上下文：

    from django.template.response import TemplateResponse

    def blog_index(request):
        return TemplateResponse(
            request, "entry_list.html", {"entries": Entry.objects.all()}
        )