---
title: "TemplateResponse 和 SimpleTemplateResponse"
version: 5.0
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/5.0/ref/template-response/
canonical: https://djangodocs.dev/zh-hans/5.0/ref/template-response/
---
# `TemplateResponse` 和 `SimpleTemplateResponse`

标准 [`HttpResponse`](/zh-hans/5.0/ref/request-response/#django.http.HttpResponse) 对象是静态结构。它们在构建时提供了一个预渲染的内容块，虽然这些内容可以修改，但它的形式并不便于进行修改。

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

TemplateResponse 提供了一种方法来实现这一点。与基本的 [`HttpResponse`](/zh-hans/5.0/ref/request-response/#django.http.HttpResponse) 对象不同，TemplateResponse 对象保留了模板和上下文的细节，这些细节是由视图提供的，用于计算响应。响应的最终输出直到需要时才会计算，在响应过程的后面。

## `SimpleTemplateResponse` 对象

#### `class SimpleTemplateResponse`

### 属性

#### `SimpleTemplateResponse.template_name`

要渲染的模板的名称。接受一个依赖于后台的模板对象（如 [`get_template()`](/zh-hans/5.0/topics/templates/#django.template.loader.get_template) 返回的模板对象）、一个模板的名称或一个模板名称列表。

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

#### `SimpleTemplateResponse.context_data`

渲染模板时要使用的上下文数据，必须是 [`dict`](https://docs.python.org/3/library/stdtypes.html#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`](#django.template.response.SimpleTemplateResponse) 对象。

**`template`**

  依赖于后台的模板对象（如 [`get_template()`](/zh-hans/5.0/topics/templates/#django.template.loader.get_template) 返回的模板对象），模板的名称，或者模板名称的列表。

**`context`**

  一个 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 的值，用于添加到模板上下文中。默认情况下，这是一个空字典。

**`content_type`**

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

**`status`**

  响应的 HTTP 状态码。

**`charset`**

  响应将被编码的字符集。如果没有给定，将从 `content_type` 中提取，如果不成功，将使用 [`DEFAULT_CHARSET`](/zh-hans/5.0/ref/settings/#std-setting-DEFAULT_CHARSET) 设置。

**`using`**

  用于加载模板的模板引擎的 [`NAME`](/zh-hans/5.0/ref/settings/#std-setting-TEMPLATES-NAME) 。

**`headers`**

  一个 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 类型的 HTTP 头信息，用于添加到响应中。

#### `SimpleTemplateResponse.resolve_context(context)`

预处理将用于渲染模板的上下文数据。接受一个 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 的上下文数据。默认情况下，返回相同的 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict)。

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

#### `SimpleTemplateResponse.resolve_template(template)`

解析用于渲染的模板实例。接受一个依赖于后台的模板对象（例如 [`get_template()`](/zh-hans/5.0/topics/templates/#django.template.loader.get_template) 返回的对象），模板的名称，或者模板名称的列表。

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

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

#### `SimpleTemplateResponse.add_post_render_callback()`

添加一个回调，将在渲染发生后被调用。该钩子可用于将某些处理操作（如缓存）推迟到渲染发生后。

如果 [`SimpleTemplateResponse`](#django.template.response.SimpleTemplateResponse) 已经被渲染，回调将被立即调用。

当调用时，回调将被传递一个单一的参数——渲染的 [`SimpleTemplateResponse`](#django.template.response.SimpleTemplateResponse) 实例。

如果回调返回一个不是 `None` 的值，这个值将被用作响应，而不是原来的响应对象（并将传递给下一个渲染后回调等）。

#### `SimpleTemplateResponse.render()`

将 `response.content` 设置为由 [`SimpleTemplateResponse.rendered_content`](#django.template.response.SimpleTemplateResponse.rendered_content) 得到的结果，运行所有的渲染后回调，并返回结果的响应对象。

`render()` 只有在第一次被调用时才会产生效果。在以后的调用中，它将返回第一次调用的结果。

## `TemplateResponse` 对象

#### `class TemplateResponse`

`TemplateResponse` 是 [`SimpleTemplateResponse`](#django.template.response.SimpleTemplateResponse) 的一个子类，它知道当前的 [`HttpRequest`](/zh-hans/5.0/ref/request-response/#django.http.HttpRequest)。

### 方法

#### `TemplateResponse.__init__(request, template, context=None, content_type=None, status=None, charset=None, using=None, headers=None)`

用给定的请求、模板、上下文、内容类型、HTTP 状态和字符集实例化一个 [`TemplateResponse`](#django.template.response.TemplateResponse) 对象。

**`request`**

  一个 [`HttpRequest`](/zh-hans/5.0/ref/request-response/#django.http.HttpRequest) 实例。

**`template`**

  依赖于后台的模板对象（如 [`get_template()`](/zh-hans/5.0/topics/templates/#django.template.loader.get_template) 返回的模板对象），模板的名称，或者模板名称的列表。

**`context`**

  一个 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 的值，用于添加到模板上下文中。默认情况下，这是一个空字典。

**`content_type`**

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

**`status`**

  响应的 HTTP 状态码。

**`charset`**

  响应将被编码的字符集。如果没有给定，将从 `content_type` 中提取，如果不成功，将使用 [`DEFAULT_CHARSET`](/zh-hans/5.0/ref/settings/#std-setting-DEFAULT_CHARSET) 设置。

**`using`**

  用于加载模板的模板引擎的 [`NAME`](/zh-hans/5.0/ref/settings/#std-setting-TEMPLATES-NAME) 。

**`headers`**

  一个 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 类型的 HTTP 头信息，用于添加到响应中。

## 渲染过程

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

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

- 当使用 [`SimpleTemplateResponse.render()`](#django.template.response.SimpleTemplateResponse.render) 方法显式渲染 `TemplateResponse` 实例时。
- 当通过指定 `response.content` 明确设置响应的内容时。
- 通过模板响应中间件后，但在通过响应中间件之前。

一个 `TemplateResponse` 只能被渲染一次。第一次调用 [`SimpleTemplateResponse.render()`](#django.template.response.SimpleTemplateResponse.render) 时，会设置响应的内容；后续的渲染调用不会改变响应内容。

然而，当显式地赋值给 `response.content` 时，更改总是会被应用。如果您想要强制重新渲染内容，可以重新评估已渲染的内容，并手动赋值响应的内容：

```pycon
# 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`](#django.template.response.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`](#django.template.response.TemplateResponse) 实例作为参数。

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

## 使用 `TemplateResponse` 和 `SimpleTemplateResponse`

一个 [`TemplateResponse`](#django.template.response.TemplateResponse) 对象可以被用于任何可以使用普通 [`django.http.HttpResponse`](/zh-hans/5.0/ref/request-response/#django.http.HttpResponse) 的地方。它也可以作为调用 [`render()`](/zh-hans/5.0/topics/http/shortcuts/#django.shortcuts.render) 的替代。

例如，下面的视图返回一个 [`TemplateResponse`](#django.template.response.TemplateResponse)，其中有一个模板和一个包含查询集的上下文：

```
from django.template.response import TemplateResponse

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