请求和响应对象

快速概述

Django 使用请求和响应对象在系统中传递状态。

当请求页面时,Django 会创建一个包含请求元数据的 HttpRequest 对象。然后 Django 加载相应的视图,并将 HttpRequest 作为第一个参数传递给视图函数。每个视图负责返回一个 HttpResponse 对象。

本文档解释了 HttpRequestHttpResponse 对象的 API,它们在 django.http 模块中定义。

HttpRequest 对象

class HttpRequest[source]

属性

除非另有说明,否则应将所有属性视为只读。

HttpRequest.scheme[source]

表示请求方案(通常为 httphttps)的字符串。

HttpRequest.body[source]

原始 HTTP 请求主体作为字节字符串。这对于以不同于传统 HTML 表单的方式处理数据很有用:二进制图像、XML 有效负载等。对于处理传统表单数据,请使用 HttpRequest.POST

您还可以使用类似文件的接口从 HttpRequest 中读取,方法是使用 HttpRequest.read()HttpRequest.readline()。在使用这些 I/O 流方法读取请求后访问 body 属性将产生 RawPostDataException

HttpRequest.path

表示请求页面完整路径的字符串,不包括方案、域名或查询字符串。

示例:"/music/bands/the_beatles/"

HttpRequest.path_info

在某些 Web 服务器配置下,主机名之后的 URL 部分被分成脚本前缀部分和路径信息部分。无论使用哪种 Web 服务器,path_info 属性始终包含路径的路径信息部分。使用它而不是 path 可以使您的代码更容易在测试和部署服务器之间移动。

例如,如果您的应用程序的 WSGIScriptAlias 设置为 "/minfo",则 path 可能是 "/minfo/music/bands/the_beatles/",而 path_info 将为 "/music/bands/the_beatles/"

HttpRequest.method

表示请求中使用的 HTTP 方法的字符串。这保证是大写的。例如

if request.method == "GET":
    do_something()
elif request.method == "POST":
    do_something_else()
HttpRequest.encoding[source]

表示用于解码表单提交数据的当前编码的字符串(或 None,这意味着使用 DEFAULT_CHARSET 设置)。您可以写入此属性以更改访问表单数据时使用的编码。任何后续属性访问(例如从 GETPOST 读取)都将使用新的 encoding 值。如果您知道表单数据不是 DEFAULT_CHARSET 编码,则很有用。

HttpRequest.content_type

表示请求的 MIME 类型的字符串,从 CONTENT_TYPE 标头解析。

HttpRequest.content_params

包含 CONTENT_TYPE 标头中包含的键/值参数的字典。

HttpRequest.GET

一个类似字典的对象,包含所有给定的 HTTP GET 参数。请参阅下面的 QueryDict 文档。

HttpRequest.POST

一个类似字典的对象,包含所有给定的 HTTP POST 参数,前提是请求包含表单数据。请参阅下面的 QueryDict 文档。如果您需要访问请求中发布的原始数据或非表单数据,请改用 HttpRequest.body 属性。

请求可以通过 POST 以空 POST 字典的形式传入——例如,如果通过 POST HTTP 方法请求表单但未包含表单数据。因此,您不应该使用 if request.POST 来检查 POST 方法的使用情况;相反,请使用 if request.method == "POST"(请参阅 HttpRequest.method)。

POST 不包含文件上传信息。请参阅 FILES

HttpRequest.COOKIES

包含所有 Cookie 的字典。键和值都是字符串。

HttpRequest.FILES

一个类似字典的对象,包含所有上传的文件。 FILES 中的每个键都是来自 <input type="file" name="">nameFILES 中的每个值都是一个 UploadedFile

更多信息请参见 管理文件

FILES 只有在请求方法为 POST 且发送到请求的 <form> 具有 enctype="multipart/form-data" 时才会包含数据。否则,FILES 将是一个空的类似字典的对象。

HttpRequest.META

一个包含所有可用 HTTP 头部的字典。 可用的头部取决于客户端和服务器,但这里有一些示例

  • CONTENT_LENGTH – 请求正文的长度(作为字符串)。

  • CONTENT_TYPE – 请求正文的 MIME 类型。

  • HTTP_ACCEPT – 响应的可接受内容类型。

  • HTTP_ACCEPT_ENCODING – 响应的可接受编码。

  • HTTP_ACCEPT_LANGUAGE – 响应的可接受语言。

  • HTTP_HOST – 客户端发送的 HTTP Host 头部。

  • HTTP_REFERER – 引用页面(如果有)。

  • HTTP_USER_AGENT – 客户端的用户代理字符串。

  • QUERY_STRING – 查询字符串,作为单个(未解析的)字符串。

  • REMOTE_ADDR – 客户端的 IP 地址。

  • REMOTE_HOST – 客户端的主机名。

  • REMOTE_USER – Web 服务器验证的用户(如果有)。

  • REQUEST_METHOD – 一个字符串,例如 "GET""POST"

  • SERVER_NAME – 服务器的主机名。

  • SERVER_PORT – 服务器的端口(作为字符串)。

除了上面给出的 CONTENT_LENGTHCONTENT_TYPE 之外,请求中的任何 HTTP 头部都会转换为 META 键,方法是将所有字符转换为大写,用下划线替换任何连字符,并在名称前面添加 HTTP_ 前缀。 因此,例如,名为 X-Bender 的头部将映射到 METAHTTP_X_BENDER

请注意,runserver 会去除名称中包含下划线的头部,因此您不会在 META 中看到它们。 这可以防止基于下划线和连字符都规范化为下划线的 WSGI 环境变量的歧义进行的头部欺骗。 它与 Nginx 和 Apache 2.4+ 等 Web 服务器的行为一致。

HttpRequest.headers 是一种更简单的方法来访问所有以 HTTP 为前缀的头部,以及 CONTENT_LENGTHCONTENT_TYPE

HttpRequest.headers[source]

一个不区分大小写的、类似字典的对象,提供对请求中所有以 HTTP 为前缀的头部(以及 Content-LengthContent-Type)的访问。

每个头部的名称在显示时都采用标题大小写样式(例如 User-Agent)。您可以不区分大小写地访问头部

>>> request.headers
{'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6', ...}

>>> "User-Agent" in request.headers
True
>>> "user-agent" in request.headers
True

>>> request.headers["User-Agent"]
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers["user-agent"]
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

>>> request.headers.get("User-Agent")
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)
>>> request.headers.get("user-agent")
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6)

例如,在 Django 模板中使用时,也可以使用下划线代替连字符查找头部

{{ request.headers.user_agent }}
HttpRequest.resolver_match

一个 ResolverMatch 实例,表示已解析的 URL。 此属性仅在 URL 解析后设置,这意味着它在所有视图中都可用,但在 URL 解析之前执行的中件件中不可用(您可以在 process_view() 中使用它)。

应用程序代码设置的属性

Django 本身不会设置这些属性,但如果您的应用程序设置了这些属性,它会使用这些属性。

HttpRequest.current_app

url 模板标签将使用它的值作为 current_app 参数传递给 reverse()

HttpRequest.urlconf

这将用作当前请求的根 URLconf,覆盖 ROOT_URLCONF 设置。 有关详细信息,请参见 Django 如何处理请求

urlconf 可以设置为 None 以恢复先前中件件所做的任何更改,并返回到使用 ROOT_URLCONF

HttpRequest.exception_reporter_filter

这将用于当前请求,而不是 DEFAULT_EXCEPTION_REPORTER_FILTER。 有关详细信息,请参见 自定义错误报告

HttpRequest.exception_reporter_class

这将用于当前请求,而不是 DEFAULT_EXCEPTION_REPORTER。 有关详细信息,请参见 自定义错误报告

中件件设置的属性

Django 的 contrib 应用程序中包含的一些中件件会在请求上设置属性。 如果您在请求上没有看到该属性,请确保 MIDDLEWARE 中列出了相应的中件件类。

HttpRequest.session

来自 SessionMiddleware:一个可读可写的、类似字典的对象,表示当前会话。

HttpRequest.site

来自 CurrentSiteMiddleware:一个 SiteRequestSite 实例,由 get_current_site() 返回,表示当前站点。

HttpRequest.user

来自 AuthenticationMiddleware:一个 AUTH_USER_MODEL 实例,表示当前登录的用户。 如果用户当前未登录,则 user 将设置为 AnonymousUser 的一个实例。 您可以使用 is_authenticated 区分它们,如下所示

if request.user.is_authenticated:
    ...  # Do something for logged-in users.
else:
    ...  # Do something for anonymous users.

auser() 方法与 auser() 方法的功能相同,但可以在异步上下文中使用。

方法

HttpRequest.auser()
Django 5.0 中新增。

来自 AuthenticationMiddleware:协程。返回一个 AUTH_USER_MODEL 实例,表示当前登录的用户。如果用户当前未登录,auser 将返回一个 AnonymousUser 实例。这与 user 属性类似,但它在异步上下文中有效。

HttpRequest.get_host()[source]

使用来自 HTTP_X_FORWARDED_HOST(如果启用了 USE_X_FORWARDED_HOST)和 HTTP_HOST 标头的信息,按此顺序返回请求的源主机。如果它们没有提供值,则该方法将使用 SERVER_NAMESERVER_PORT 的组合,如 PEP 3333 中所述。

示例:"127.0.0.1:8000"

如果主机不在 ALLOWED_HOSTS 中或域名根据 RFC 1034/1035 无效,则引发 django.core.exceptions.DisallowedHost

注意

当主机位于多个代理后面时,get_host() 方法会失败。一种解决方案是使用中间件重写代理标头,如下例所示

class MultipleProxyMiddleware:
    FORWARDED_FOR_FIELDS = [
        "HTTP_X_FORWARDED_FOR",
        "HTTP_X_FORWARDED_HOST",
        "HTTP_X_FORWARDED_SERVER",
    ]

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        """
        Rewrites the proxy headers so that only the most
        recent proxy is used.
        """
        for field in self.FORWARDED_FOR_FIELDS:
            if field in request.META:
                if "," in request.META[field]:
                    parts = request.META[field].split(",")
                    request.META[field] = parts[-1].strip()
        return self.get_response(request)

此中间件应位于任何其他依赖于 get_host() 值的中间件之前,例如 CommonMiddlewareCsrfViewMiddleware

HttpRequest.get_port()[source]

使用来自 HTTP_X_FORWARDED_PORT(如果启用了 USE_X_FORWARDED_PORT)和 SERVER_PORT META 变量的信息,按此顺序返回请求的源端口。

HttpRequest.get_full_path()[source]

返回 path,以及适用的附加查询字符串。

示例:"/music/bands/the_beatles/?print=true"

HttpRequest.get_full_path_info()[source]

类似于 get_full_path(),但使用 path_info 而不是 path

示例:"/minfo/music/bands/the_beatles/?print=true"

HttpRequest.build_absolute_uri(location=None)[source]

返回 location 的绝对 URI 形式。如果未提供位置,则位置将设置为 request.get_full_path()

如果位置已经是绝对 URI,则不会更改。否则,将使用此请求中可用的服务器变量构建绝对 URI。例如

>>> request.build_absolute_uri()
'https://example.com/music/bands/the_beatles/?print=true'
>>> request.build_absolute_uri("/bands/")
'https://example.com/bands/'
>>> request.build_absolute_uri("https://example2.com/bands/")
'https://example2.com/bands/'

注意

不建议在同一站点上混合使用 HTTP 和 HTTPS,因此 build_absolute_uri() 将始终生成与当前请求相同的方案的绝对 URI。如果您需要将用户重定向到 HTTPS,最好让您的 Web 服务器将所有 HTTP 流量重定向到 HTTPS。

返回签名 cookie 的 cookie 值,或者如果签名不再有效则引发 django.core.signing.BadSignature 异常。如果您提供 default 参数,则异常将被抑制,并且将返回该默认值。

可选的 salt 参数可用于提供针对密钥的暴力破解攻击的额外保护。如果提供,则将针对附加到 cookie 值的签名时间戳检查 max_age 参数,以确保 cookie 不超过 max_age 秒。

例如

>>> request.get_signed_cookie("name")
'Tony'
>>> request.get_signed_cookie("name", salt="name-salt")
'Tony' # assuming cookie was set using the same salt
>>> request.get_signed_cookie("nonexistent-cookie")
KeyError: 'nonexistent-cookie'
>>> request.get_signed_cookie("nonexistent-cookie", False)
False
>>> request.get_signed_cookie("cookie-that-was-tampered-with")
BadSignature: ...
>>> request.get_signed_cookie("name", max_age=60)
SignatureExpired: Signature age 1677.3839159 > 60 seconds
>>> request.get_signed_cookie("name", False, max_age=60)
False

有关更多信息,请参阅 加密签名

HttpRequest.is_secure()[source]

如果请求安全,则返回 True;也就是说,如果它是使用 HTTPS 发出的。

HttpRequest.accepts(mime_type)[source]

如果请求的 Accept 标头与 mime_type 参数匹配,则返回 True

>>> request.accepts("text/html")
True

大多数浏览器默认发送 Accept: */*,因此这将对所有内容类型返回 True。在 API 请求中设置明确的 Accept 标头对于仅为这些使用者返回不同的内容类型很有用。请参阅 内容协商示例 中使用 accepts() 向 API 使用者返回不同内容的示例。

如果响应因 Accept 标头的内容而异,并且您正在使用某种形式的缓存(如 Django 的 cache middleware),则应使用 vary_on_headers('Accept') 装饰视图,以便正确缓存响应。

HttpRequest.read(size=None)[source]
HttpRequest.readline()[source]
HttpRequest.readlines()[source]
HttpRequest.__iter__()[source]

实现文件类接口,用于读取 HttpRequest 实例的方法。这使得以流式方式使用传入请求成为可能。一个常见的用例是使用迭代解析器处理大型 XML 有效负载,而无需在内存中构建完整的 XML 树。

鉴于此标准接口,可以将 HttpRequest 实例直接传递给 XML 解析器,例如 ElementTree

import xml.etree.ElementTree as ET

for element in ET.iterparse(request):
    process(element)

QueryDict 对象

class QueryDict[source]

HttpRequest 对象中,GETPOST 属性是 django.http.QueryDict 的实例,这是一个类似字典的类,专门用于处理同一键的多个值。这是必要的,因为某些 HTML 表单元素,特别是 <select multiple>,会为同一个键传递多个值。

在正常的请求/响应周期中访问 request.POSTrequest.GET 中的 QueryDict 时,它们将是不可变的。要获取可变版本,您需要使用 QueryDict.copy()

方法

QueryDict 实现所有标准字典方法,因为它是一个字典的子类。此处概述了异常情况

QueryDict.__init__(query_string=None, mutable=False, encoding=None)[source]

基于 query_string 实例化 QueryDict 对象。

>>> QueryDict("a=1&a=2&c=3")
<QueryDict: {'a': ['1', '2'], 'c': ['3']}>

如果未传入 query_string,则生成的 QueryDict 将为空(它将没有键或值)。

您遇到的大多数 QueryDict,尤其是 request.POSTrequest.GET 中的那些,将是不可变的。如果您自己正在实例化一个,则可以通过将其 __init__() 中传递 mutable=True 来使其可变。

用于设置键和值的字符串将从 encoding 转换为 str。如果未设置 encoding,则默认为 DEFAULT_CHARSET

classmethod QueryDict.fromkeys(iterable, value='', mutable=False, encoding=None)[source]

使用来自 iterable 的键和每个值等于 value 创建一个新的 QueryDict。例如

>>> QueryDict.fromkeys(["a", "a", "b"], value="val")
<QueryDict: {'a': ['val', 'val'], 'b': ['val']}>
QueryDict.__getitem__(key)

返回给定键的值。如果键有多个值,则返回最后一个值。如果键不存在,则引发 django.utils.datastructures.MultiValueDictKeyError。(这是 Python 标准 KeyError 的子类,因此您可以坚持捕获 KeyError。)

QueryDict.__setitem__(key, value)[source]

将给定键设置为 [value](其单个元素为 value 的列表)。请注意,这与其他具有副作用的字典函数一样,只能在可变 QueryDict(例如通过 QueryDict.copy() 创建的)上调用。

QueryDict.__contains__(key)

如果设置了给定键,则返回 True。这允许您执行以下操作,例如 if "foo" in request.GET

QueryDict.get(key, default=None)

使用与 __getitem__() 相同的逻辑,并带有在键不存在时返回默认值的钩子。

QueryDict.setdefault(key, default=None)[source]

类似于 dict.setdefault(),除了它在内部使用 __setitem__()

QueryDict.update(other_dict)

接受 QueryDict 或字典。类似于 dict.update(),除了它追加到当前字典项而不是替换它们。例如

>>> q = QueryDict("a=1", mutable=True)
>>> q.update({"a": "2"})
>>> q.getlist("a")
['1', '2']
>>> q["a"]  # returns the last
'2'
QueryDict.items()

类似于 dict.items(),除了它使用与 __getitem__() 相同的最后一个值逻辑,并返回迭代器对象而不是视图对象。例如

>>> q = QueryDict("a=1&a=2&a=3")
>>> list(q.items())
[('a', '3')]
QueryDict.values()

类似于 dict.values(),但它使用了与 __getitem__() 相同的最后一个值逻辑,并返回一个迭代器而不是视图对象。例如

>>> q = QueryDict("a=1&a=2&a=3")
>>> list(q.values())
['3']

此外,QueryDict 具有以下方法

QueryDict.copy()[source]

使用 copy.deepcopy() 返回对象的副本。即使原始对象不可变,此副本也将是可变的。

QueryDict.getlist(key, default=None)

返回具有请求键的数据列表。如果键不存在且 defaultNone,则返回空列表。除非提供的默认值不是列表,否则它保证返回一个列表。

QueryDict.setlist(key, list_)[source]

将给定键设置为 list_(与 __setitem__() 不同)。

QueryDict.appendlist(key, item)[source]

将一个项目追加到与键关联的内部列表中。

QueryDict.setlistdefault(key, default_list=None)[source]

类似于 setdefault(),但它接受一个值列表而不是单个值。

QueryDict.lists()

类似于 items(),但它包含字典中每个成员的所有值(作为一个列表)。例如

>>> q = QueryDict("a=1&a=2&a=3")
>>> q.lists()
[('a', ['1', '2', '3'])]
QueryDict.pop(key)[source]

返回给定键的值列表并将其从字典中删除。如果键不存在,则引发 KeyError。例如

>>> q = QueryDict("a=1&a=2&a=3", mutable=True)
>>> q.pop("a")
['1', '2', '3']
QueryDict.popitem()[source]

删除字典中的任意成员(因为没有排序的概念),并返回一个包含键和该键所有值的列表的两个值的元组。在空字典上调用时引发 KeyError。例如

>>> q = QueryDict("a=1&a=2&a=3", mutable=True)
>>> q.popitem()
('a', ['1', '2', '3'])
QueryDict.dict()

返回 QueryDictdict 表示形式。对于 QueryDict 中的每个 (键,列表) 对,dict 将具有 (键,项目),其中项目是列表中的一个元素,使用与 QueryDict.__getitem__() 相同的逻辑。

>>> q = QueryDict("a=1&a=3&a=5")
>>> q.dict()
{'a': '5'}
QueryDict.urlencode(safe=None)[source]

返回查询字符串格式的数据字符串。例如

>>> q = QueryDict("a=2&b=3&b=5")
>>> q.urlencode()
'a=2&b=3&b=5'

使用 safe 参数传递不需要编码的字符。例如

>>> q = QueryDict(mutable=True)
>>> q["next"] = "/a&b/"
>>> q.urlencode(safe="/")
'next=/a%26b/'

HttpResponse 对象

class HttpResponse[source]

与由 Django 自动创建的 HttpRequest 对象相反,HttpResponse 对象由您负责。您编写的每个视图都负责实例化、填充和返回一个 HttpResponse

HttpResponse 类位于 django.http 模块中。

用法

传递字符串

典型用法是将页面内容(作为字符串、字节字符串或 memoryview)传递给 HttpResponse 构造函数。

>>> from django.http import HttpResponse
>>> response = HttpResponse("Here's the text of the web page.")
>>> response = HttpResponse("Text only, please.", content_type="text/plain")
>>> response = HttpResponse(b"Bytestrings are also accepted.")
>>> response = HttpResponse(memoryview(b"Memoryview as well."))

但是,如果您想增量添加内容,可以使用 response 作为类文件对象。

>>> response = HttpResponse()
>>> response.write("<p>Here's the text of the web page.</p>")
>>> response.write("<p>Here's another paragraph.</p>")

传递迭代器

最后,您可以将 HttpResponse 传递一个迭代器而不是字符串。 HttpResponse 将立即使用迭代器,将其内容存储为字符串,然后将其丢弃。具有 close() 方法的对象(如文件和生成器)将立即关闭。

如果您需要将响应从迭代器流式传输到客户端,则必须改为使用 StreamingHttpResponse 类。

设置标头字段

要设置或删除响应中的标头字段,请使用 HttpResponse.headers

>>> response = HttpResponse()
>>> response.headers["Age"] = 120
>>> del response.headers["Age"]

您还可以通过将响应视为字典来操作标头。

>>> response = HttpResponse()
>>> response["Age"] = 120
>>> del response["Age"]

这代理到 HttpResponse.headers,并且是 HttpResponse 提供的原始接口。

使用此接口时,与字典不同,如果标头字段不存在,则 del 不会引发 KeyError

您也可以在实例化时设置标头。

>>> response = HttpResponse(headers={"Age": 120})

对于设置 Cache-ControlVary 标头字段,建议使用 patch_cache_control()patch_vary_headers() 方法来自 django.utils.cache,因为这些字段可以具有多个以逗号分隔的值。“patch”方法确保不会删除其他值,例如由中间件添加的值。

HTTP 标头字段不能包含换行符。尝试设置包含换行符 (CR 或 LF) 的标头字段将引发 BadHeaderError

告诉浏览器将响应视为文件附件

要告诉浏览器将响应视为文件附件,请设置 Content-TypeContent-Disposition 标头。例如,以下是如何返回 Microsoft Excel 电子表格

>>> response = HttpResponse(
...     my_data,
...     headers={
...         "Content-Type": "application/vnd.ms-excel",
...         "Content-Disposition": 'attachment; filename="foo.xls"',
...     },
... )

Content-Disposition 标头与 Django 无关,但其语法很容易忘记,因此我们将其包含在此处。

属性

HttpResponse.content[source]

表示内容的字节字符串,如有必要,会从字符串编码。

HttpResponse.cookies

一个 http.cookies.SimpleCookie 对象,包含响应中包含的 cookie。

HttpResponse.headers

一个不区分大小写的、类似字典的对象,提供对响应中所有 HTTP 标头的接口,除了 Set-Cookie 标头。请参阅 设置标头字段HttpResponse.cookies

HttpResponse.charset

一个字符串,表示响应将以其编码的字符集。如果在 HttpResponse 实例化时未给出,它将从 content_type 中提取,如果提取不成功,则将使用 DEFAULT_CHARSET 设置。

HttpResponse.status_code

响应的 HTTP 状态代码

除非 reason_phrase 被显式设置,否则在构造函数之外修改 status_code 的值也会修改 reason_phrase 的值。

HttpResponse.reason_phrase

响应的 HTTP 原因短语。它使用 HTTP 标准 的默认原因短语。

除非显式设置,否则 reason_phrasestatus_code 的值确定。

HttpResponse.streaming

这始终为 False

此属性的存在是为了使中间件能够将流式响应与常规响应区分开来。

HttpResponse.closed

如果响应已关闭,则为 True

方法

HttpResponse.__init__(content=b'', content_type=None, status=200, reason=None, charset=None, headers=None)[source]

使用给定的页面内容、内容类型和标头实例化 HttpResponse 对象。

content 最常见的是迭代器、字节字符串、memoryview 或字符串。其他类型将通过对其字符串表示形式进行编码转换为字节字符串。迭代器应返回字符串或字节字符串,这些字符串将连接在一起以形成响应的内容。

content_type 是 MIME 类型,可以选择性地由字符集编码补充,并用于填充 HTTP Content-Type 标头。如果未指定,则由 'text/html'DEFAULT_CHARSET 设置(默认情况下)形成:"text/html; charset=utf-8"

status 是响应的 HTTP 状态代码。您可以使用 Python 的 http.HTTPStatus 获取有意义的别名,例如 HTTPStatus.NO_CONTENT

reason 是 HTTP 响应短语。如果未提供,将使用默认短语。

charset 是响应将以其编码的字符集。如果未给出,它将从 content_type 中提取,如果提取不成功,则将使用 DEFAULT_CHARSET 设置。

headers 是响应的 HTTP 标头的 dict

HttpResponse.__setitem__(header, value)

将给定的标头名称设置为给定的值。headervalue 都应为字符串。

HttpResponse.__delitem__(header)

删除具有给定名称的标头。如果标头不存在,则静默失败。不区分大小写。

HttpResponse.__getitem__(header)

返回给定标头名称的值。不区分大小写。

HttpResponse.get(header, alternate=None)

返回给定标头的值,如果标头不存在,则返回 alternate

HttpResponse.has_header(header)

根据对具有给定名称的标头的区分大小写检查返回 TrueFalse

HttpResponse.items()

类似于响应中 HTTP 头部的 dict.items()

HttpResponse.setdefault(header, value)

除非已设置,否则设置头部。

设置 Cookie。参数与 Python 标准库中的 Morsel Cookie 对象相同。

  • max_age 应该是一个 timedelta 对象,一个以秒为单位的整数,或者 None(默认值),如果 Cookie 应该只持续到客户端浏览器的会话结束。如果未指定 expires,则会计算它。

  • expires 应该是一个格式为 "Wdy, DD-Mon-YY HH:MM:SS GMT" 的字符串,或者一个 UTC 时间的 datetime.datetime 对象。如果 expires 是一个 datetime 对象,则会计算 max_age

  • 如果要设置跨域 Cookie,请使用 domain。例如,domain="example.com" 将设置一个可被 www.example.com、blog.example.com 等域名读取的 Cookie。否则,Cookie 只能被设置它的域名读取。

  • 如果希望 Cookie 仅在使用 https 方案发出请求时发送到服务器,请使用 secure=True

  • 如果要阻止客户端 JavaScript 访问 Cookie,请使用 httponly=True

    HttpOnly 是包含在 Set-Cookie HTTP 响应头中的一个标志。它是 RFC 6265 Cookie 标准的一部分,可以有效地降低客户端脚本访问受保护的 Cookie 数据的风险。

  • 使用 samesite='Strict'samesite='Lax' 告诉浏览器在执行跨源请求时不要发送此 Cookie。SameSite 并非所有浏览器都支持,因此它不能替代 Django 的 CSRF 保护,而是一种纵深防御措施。

    使用 samesite='None'(字符串)明确表示此 Cookie 会随所有同站和跨站请求一起发送。

警告

RFC 6265 指出用户代理应该支持至少 4096 字节的 Cookie。对于许多浏览器来说,这也是最大大小。如果尝试存储大于 4096 字节的 Cookie,Django 不会引发异常,但许多浏览器不会正确设置 Cookie。

类似于 set_cookie(),但在设置之前 使用加密签名 Cookie。与 HttpRequest.get_signed_cookie() 结合使用。您可以使用可选的 salt 参数来增强密钥强度,但您需要记住将其传递给相应的 HttpRequest.get_signed_cookie() 调用。

删除具有给定键的 Cookie。如果键不存在,则静默失败。

由于 Cookie 的工作方式,pathdomain 应该与您在 set_cookie() 中使用的值相同,否则 Cookie 可能不会被删除。

HttpResponse.close()

此方法在请求结束时由 WSGI 服务器直接调用。

HttpResponse.write(content)[source]

此方法使 HttpResponse 实例成为类文件对象。

HttpResponse.flush()

此方法使 HttpResponse 实例成为类文件对象。

HttpResponse.tell()[source]

此方法使 HttpResponse 实例成为类文件对象。

HttpResponse.getvalue()[source]

返回 HttpResponse.content 的值。此方法使 HttpResponse 实例成为类流对象。

HttpResponse.readable()

始终为 False。此方法使 HttpResponse 实例成为类流对象。

HttpResponse.seekable()

始终为 False。此方法使 HttpResponse 实例成为类流对象。

HttpResponse.writable()[source]

始终为 True。此方法使 HttpResponse 实例成为类流对象。

HttpResponse.writelines(lines)[source]

将行列表写入响应。不会添加行分隔符。此方法使 HttpResponse 实例成为类流对象。

HttpResponse 子类

Django 包含许多用于处理不同类型 HTTP 响应的 HttpResponse 子类。与 HttpResponse 一样,这些子类也位于 django.http 中。

class HttpResponseRedirect[source]

构造函数的第一个参数是必需的 - 要重定向到的路径。这可以是完整的 URL(例如 'https://www.yahoo.com/search/')、不带域名的绝对路径(例如 '/search/'),甚至相对路径(例如 'search/')。在最后一种情况下,客户端浏览器将根据当前路径自行重建完整的 URL。有关其他可选构造函数参数,请参阅 HttpResponse。请注意,这将返回 HTTP 状态代码 302。

url

此只读属性表示响应将重定向到的 URL(相当于 Location 响应头)。

class HttpResponsePermanentRedirect[source]

HttpResponseRedirect 类似,但它返回永久重定向(HTTP 状态代码 301)而不是“已找到”重定向(状态代码 302)。

class HttpResponseNotModified[source]

构造函数不接受任何参数,也不应向此响应添加任何内容。使用此方法来指定页面自用户上次请求以来未修改(状态代码 304)。

class HttpResponseBadRequest[source]

HttpResponse 的行为相同,但使用 400 状态代码。

class HttpResponseNotFound[source]

HttpResponse 的行为相同,但使用 404 状态代码。

class HttpResponseForbidden[source]

HttpResponse 的行为相同,但使用 403 状态代码。

class HttpResponseNotAllowed[source]

HttpResponse 类似,但使用 405 状态代码。构造函数的第一个参数是必需的:允许的方法列表(例如 ['GET', 'POST'])。

class HttpResponseGone[source]

HttpResponse 的行为相同,但使用 410 状态代码。

class HttpResponseServerError[source]

HttpResponse 的行为相同,但使用 500 状态代码。

注意

如果 HttpResponse 的自定义子类实现了 render 方法,Django 将将其视为模拟 SimpleTemplateResponse,并且 render 方法本身必须返回一个有效的响应对象。

自定义响应类

如果您发现自己需要 Django 未提供的响应类,则可以借助 http.HTTPStatus 创建它。例如

from http import HTTPStatus
from django.http import HttpResponse


class HttpResponseNoContent(HttpResponse):
    status_code = HTTPStatus.NO_CONTENT

JsonResponse 对象

class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)[source]

一个 HttpResponse 子类,有助于创建 JSON 编码的响应。它继承了其超类的大部分行为,但也有一些区别

其默认的 Content-Type 标头设置为 application/json

第一个参数 data 应该是一个 dict 实例。如果 safe 参数设置为 False(见下文),它可以是任何可 JSON 序列化的对象。

默认情况下,encoderdjango.core.serializers.json.DjangoJSONEncoder,它将用于序列化数据。有关此序列化程序的更多详细信息,请参阅 JSON 序列化

布尔参数 safe 默认为 True。如果将其设置为 False,则可以传递任何对象进行序列化(否则仅允许 dict 实例)。如果 safeTrue 并且第一个参数传递的不是 dict 对象,则会引发 TypeError

参数 json_dumps_params 是一个字典,其中包含要传递给用于生成响应的 json.dumps() 调用的关键字参数。

用法

典型用法如下所示

>>> from django.http import JsonResponse
>>> response = JsonResponse({"foo": "bar"})
>>> response.content
b'{"foo": "bar"}'

序列化非字典对象

为了序列化除 dict 之外的对象,您必须将 safe 参数设置为 False

>>> response = JsonResponse([1, 2, 3], safe=False)

如果不传递 safe=False,则会引发 TypeError

请注意,基于 dict 对象的 API 具有更好的扩展性、灵活性,并且更易于维护向前兼容性。因此,您应该避免在 JSON 编码的响应中使用非字典对象。

警告

ECMAScript 第 5 版之前,可以对 JavaScript 的Array构造函数进行攻击。出于这个原因,Django 默认不允许将非字典对象传递给JsonResponse构造函数。但是,大多数现代浏览器都实现了 ECMAScript 5,它消除了这种攻击途径。因此,可以禁用此安全预防措施。

更改默认 JSON 编码器

如果您需要使用不同的 JSON 编码器类,可以将encoder参数传递给构造函数方法

>>> response = JsonResponse(data, encoder=MyJSONEncoder)

StreamingHttpResponse 对象

class StreamingHttpResponse[source]

StreamingHttpResponse 类用于将响应从 Django 流式传输到浏览器。

高级用法

StreamingHttpResponse 稍微复杂一些,因为了解您是在 WSGI 下同步服务应用程序还是在 ASGI 下异步服务应用程序非常重要,并相应地调整用法。

请仔细阅读这些说明。

在 WSGI 下使用StreamingHttpResponse的一个示例是在生成响应需要花费太长时间或使用太多内存时流式传输内容。例如,它对于生成大型 CSV 文件很有用。

但是,这样做时需要考虑性能问题。在 WSGI 下的 Django 旨在用于短时请求。流式传输响应将在整个响应持续时间内绑定工作进程。这可能会导致性能下降。

一般来说,您应该在请求-响应周期之外执行耗时的任务,而不是使用流式传输响应。

但是,在 ASGI 下服务时,StreamingHttpResponse无需在等待 I/O 时阻止其他请求被服务。这为流式传输内容的长期请求以及实现长轮询和服务器发送事件等模式提供了可能性。

即使在 ASGI 下,也请注意,StreamingHttpResponse 仅应在绝对需要在将数据传输到客户端之前不迭代整个内容的情况下使用。由于无法访问内容,因此许多中间件无法正常工作。例如,无法为流式传输响应生成ETagContent-Length标头。

StreamingHttpResponse 不是HttpResponse的子类,因为它具有略微不同的 API。但是,它几乎相同,以下是一些明显的区别

  • 它应该接收一个迭代器,该迭代器生成字节字符串、memoryview或字符串作为内容。在 WSGI 下服务时,这应该是一个同步迭代器。在 ASGI 下服务时,这应该是一个异步迭代器。

  • 您无法访问其内容,除非通过迭代响应对象本身。这仅在将响应返回到客户端时才会发生:您不应该自己迭代响应。

    在 WSGI 下,响应将被同步迭代。在 ASGI 下,响应将被异步迭代。(这就是迭代器类型必须与您使用的协议匹配的原因。)

    为了避免崩溃,不正确的迭代器类型将在迭代期间映射到正确的类型,并且会发出警告,但是为了做到这一点,必须完全使用迭代器,这违背了使用StreamingHttpResponse的初衷。

  • 它没有content属性。相反,它具有streaming_content属性。这可以在中间件中用于包装响应可迭代对象,但不应使用。

  • 您不能使用类似文件的对象tell()write()方法。这样做会引发异常。

HttpResponseBase基类在HttpResponseStreamingHttpResponse之间是通用的。

属性

StreamingHttpResponse.streaming_content[source]

响应内容的迭代器,根据HttpResponse.charset进行字节字符串编码。

StreamingHttpResponse.status_code

响应的HTTP 状态代码

除非显式设置reason_phrase,否则在构造函数外部修改status_code的值也会修改reason_phrase的值。

StreamingHttpResponse.reason_phrase

响应的 HTTP 原因短语。它使用HTTP 标准的默认原因短语。

除非显式设置,否则reason_phrasestatus_code的值确定。

StreamingHttpResponse.streaming

这始终为True

StreamingHttpResponse.is_async

布尔值,指示StreamingHttpResponse.streaming_content是否为异步迭代器。

这对于需要包装StreamingHttpResponse.streaming_content的中间件很有用。

处理断开连接

Django 5.0 中新增。

如果客户端在流式传输响应期间断开连接,Django 将取消处理响应的协程。如果要手动清理资源,可以通过捕获asyncio.CancelledError来实现。

async def streaming_response():
    try:
        # Do some work here
        async for chunk in my_streaming_iterator():
            yield chunk
    except asyncio.CancelledError:
        # Handle disconnect
        ...
        raise


async def my_streaming_view(request):
    return StreamingHttpResponse(streaming_response())

此示例仅显示如何在响应流式传输时处理客户端断开连接。如果您在返回StreamingHttpResponse对象之前在视图中执行长时间运行的操作,那么您可能还需要在视图本身中处理断开连接

FileResponse 对象

class FileResponse(open_file, as_attachment=False, filename='', **kwargs)[source]

FileResponseStreamingHttpResponse 的一个子类,针对二进制文件进行了优化。如果 wsgi 服务器提供了wsgi.file_wrapper,它将使用该功能,否则它将以小块的形式流式传输文件。

如果as_attachment=True,则Content-Disposition标头设置为attachment,这要求浏览器向用户提供文件以供下载。否则,仅当文件名可用时,才会设置值为inline(浏览器默认值)的Content-Disposition标头。

如果 open_file 没有名称,或者 open_file 的名称不合适,请使用 filename 参数提供自定义文件名。请注意,如果您传递类似于 io.BytesIO 的类文件对象,则您需要在将其传递给 FileResponse 之前对其进行 seek() 操作。

当可以从 open_file 的内容中推测出 Content-Length 标头时,会自动设置该标头。

当可以从 filenameopen_file 的名称中推测出 Content-Type 标头时,会自动设置该标头。

FileResponse 接受任何具有二进制内容的类文件对象,例如以二进制模式打开的文件,如下所示

>>> from django.http import FileResponse
>>> response = FileResponse(open("myfile.png", "rb"))

文件将自动关闭,因此不要使用上下文管理器打开它。

在 ASGI 下使用

Python 的文件 API 是同步的。这意味着必须完全使用文件才能在 ASGI 下提供服务。

为了异步地流式传输文件,您需要使用提供异步文件 API 的第三方包,例如 aiofiles

方法

FileResponse.set_headers(open_file)[source]

此方法在响应初始化期间自动调用,并根据 open_file 设置各种标头(Content-LengthContent-TypeContent-Disposition)。

HttpResponseBase

class HttpResponseBase[source]

HttpResponseBase 类是所有 Django 响应的通用类。不应直接使用它来创建响应,但它对于类型检查很有用。

返回顶部