请求和响应对象¶
快速概述¶
Django 使用请求和响应对象在系统中传递状态。
当请求页面时,Django 会创建一个包含请求元数据的 HttpRequest 对象。然后 Django 加载相应的视图,并将 HttpRequest 作为第一个参数传递给视图函数。每个视图负责返回一个 HttpResponse 对象。
本文档解释了 HttpRequest 和 HttpResponse 对象的 API,它们在 django.http 模块中定义。
HttpRequest 对象¶
属性¶
除非另有说明,否则应将所有属性视为只读。
- 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设置)。您可以写入此属性以更改访问表单数据时使用的编码。任何后续属性访问(例如从GET或POST读取)都将使用新的encoding值。如果您知道表单数据不是DEFAULT_CHARSET编码,则很有用。
- HttpRequest.content_type¶
表示请求的 MIME 类型的字符串,从
CONTENT_TYPE标头解析。
- HttpRequest.content_params¶
包含
CONTENT_TYPE标头中包含的键/值参数的字典。
- 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="">的name。FILES中的每个值都是一个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_LENGTH和CONTENT_TYPE之外,请求中的任何 HTTP 头部都会转换为META键,方法是将所有字符转换为大写,用下划线替换任何连字符,并在名称前面添加HTTP_前缀。 因此,例如,名为X-Bender的头部将映射到META键HTTP_X_BENDER。请注意,
runserver会去除名称中包含下划线的头部,因此您不会在META中看到它们。 这可以防止基于下划线和连字符都规范化为下划线的 WSGI 环境变量的歧义进行的头部欺骗。 它与 Nginx 和 Apache 2.4+ 等 Web 服务器的行为一致。HttpRequest.headers是一种更简单的方法来访问所有以 HTTP 为前缀的头部,以及CONTENT_LENGTH和CONTENT_TYPE。
- HttpRequest.headers[source]¶
一个不区分大小写的、类似字典的对象,提供对请求中所有以 HTTP 为前缀的头部(以及
Content-Length和Content-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.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:一个Site或RequestSite实例,由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_NAME和SERVER_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()值的中间件之前,例如CommonMiddleware或CsrfViewMiddleware。
- HttpRequest.get_port()[source]¶
使用来自
HTTP_X_FORWARDED_PORT(如果启用了USE_X_FORWARDED_PORT)和SERVER_PORTMETA变量的信息,按此顺序返回请求的源端口。
- 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。
- HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)[source]¶
返回签名 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.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.__iter__()[source]¶
实现文件类接口,用于读取
HttpRequest实例的方法。这使得以流式方式使用传入请求成为可能。一个常见的用例是使用迭代解析器处理大型 XML 有效负载,而无需在内存中构建完整的 XML 树。鉴于此标准接口,可以将
HttpRequest实例直接传递给 XML 解析器,例如ElementTreeimport xml.etree.ElementTree as ET for element in ET.iterparse(request): process(element)
QueryDict 对象¶
在 HttpRequest 对象中,GET 和 POST 属性是 django.http.QueryDict 的实例,这是一个类似字典的类,专门用于处理同一键的多个值。这是必要的,因为某些 HTML 表单元素,特别是 <select multiple>,会为同一个键传递多个值。
在正常的请求/响应周期中访问 request.POST 和 request.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.POST和request.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)¶
返回具有请求键的数据列表。如果键不存在且
default为None,则返回空列表。除非提供的默认值不是列表,否则它保证返回一个列表。
- QueryDict.setlist(key, list_)[source]¶
将给定键设置为
list_(与__setitem__()不同)。
- 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()¶
返回
QueryDict的dict表示形式。对于QueryDict中的每个 (键,列表) 对,dict将具有 (键,项目),其中项目是列表中的一个元素,使用与QueryDict.__getitem__()相同的逻辑。>>> q = QueryDict("a=1&a=3&a=5") >>> q.dict() {'a': '5'}
HttpResponse 对象¶
与由 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-Control 和 Vary 标头字段,建议使用 patch_cache_control() 和 patch_vary_headers() 方法来自 django.utils.cache,因为这些字段可以具有多个以逗号分隔的值。“patch”方法确保不会删除其他值,例如由中间件添加的值。
HTTP 标头字段不能包含换行符。尝试设置包含换行符 (CR 或 LF) 的标头字段将引发 BadHeaderError。
告诉浏览器将响应视为文件附件¶
要告诉浏览器将响应视为文件附件,请设置 Content-Type 和 Content-Disposition 标头。例如,以下是如何返回 Microsoft Excel 电子表格
>>> response = HttpResponse(
... my_data,
... headers={
... "Content-Type": "application/vnd.ms-excel",
... "Content-Disposition": 'attachment; filename="foo.xls"',
... },
... )
Content-Disposition 标头与 Django 无关,但其语法很容易忘记,因此我们将其包含在此处。
属性¶
- 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_phrase由status_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 类型,可以选择性地由字符集编码补充,并用于填充 HTTPContent-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)¶
将给定的标头名称设置为给定的值。
header和value都应为字符串。
- HttpResponse.__delitem__(header)¶
删除具有给定名称的标头。如果标头不存在,则静默失败。不区分大小写。
- HttpResponse.__getitem__(header)¶
返回给定标头名称的值。不区分大小写。
- HttpResponse.get(header, alternate=None)¶
返回给定标头的值,如果标头不存在,则返回
alternate。
- HttpResponse.has_header(header)¶
根据对具有给定名称的标头的区分大小写检查返回
True或False。
- HttpResponse.items()¶
类似于响应中 HTTP 头部的
dict.items()。
- HttpResponse.setdefault(header, value)¶
除非已设置,否则设置头部。
- HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False, samesite=None)¶
设置 Cookie。参数与 Python 标准库中的
MorselCookie 对象相同。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。
- HttpResponse.set_signed_cookie(key, value, salt='', max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False, samesite=None)¶
类似于
set_cookie(),但在设置之前 使用加密签名 Cookie。与HttpRequest.get_signed_cookie()结合使用。您可以使用可选的salt参数来增强密钥强度,但您需要记住将其传递给相应的HttpRequest.get_signed_cookie()调用。
- HttpResponse.delete_cookie(key, path='/', domain=None, samesite=None)¶
删除具有给定键的 Cookie。如果键不存在,则静默失败。
由于 Cookie 的工作方式,
path和domain应该与您在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 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 序列化的对象。默认情况下,
encoder为django.core.serializers.json.DjangoJSONEncoder,它将用于序列化数据。有关此序列化程序的更多详细信息,请参阅 JSON 序列化。布尔参数
safe默认为True。如果将其设置为False,则可以传递任何对象进行序列化(否则仅允许dict实例)。如果safe为True并且第一个参数传递的不是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 对象¶
StreamingHttpResponse 类用于将响应从 Django 流式传输到浏览器。
在 WSGI 下使用StreamingHttpResponse的一个示例是在生成响应需要花费太长时间或使用太多内存时流式传输内容。例如,它对于生成大型 CSV 文件很有用。
但是,这样做时需要考虑性能问题。在 WSGI 下的 Django 旨在用于短时请求。流式传输响应将在整个响应持续时间内绑定工作进程。这可能会导致性能下降。
一般来说,您应该在请求-响应周期之外执行耗时的任务,而不是使用流式传输响应。
但是,在 ASGI 下服务时,StreamingHttpResponse无需在等待 I/O 时阻止其他请求被服务。这为流式传输内容的长期请求以及实现长轮询和服务器发送事件等模式提供了可能性。
即使在 ASGI 下,也请注意,StreamingHttpResponse 仅应在绝对需要在将数据传输到客户端之前不迭代整个内容的情况下使用。由于无法访问内容,因此许多中间件无法正常工作。例如,无法为流式传输响应生成ETag和Content-Length标头。
StreamingHttpResponse 不是HttpResponse的子类,因为它具有略微不同的 API。但是,它几乎相同,以下是一些明显的区别
它应该接收一个迭代器,该迭代器生成字节字符串、
memoryview或字符串作为内容。在 WSGI 下服务时,这应该是一个同步迭代器。在 ASGI 下服务时,这应该是一个异步迭代器。您无法访问其内容,除非通过迭代响应对象本身。这仅在将响应返回到客户端时才会发生:您不应该自己迭代响应。
在 WSGI 下,响应将被同步迭代。在 ASGI 下,响应将被异步迭代。(这就是迭代器类型必须与您使用的协议匹配的原因。)
为了避免崩溃,不正确的迭代器类型将在迭代期间映射到正确的类型,并且会发出警告,但是为了做到这一点,必须完全使用迭代器,这违背了使用
StreamingHttpResponse的初衷。它没有
content属性。相反,它具有streaming_content属性。这可以在中间件中用于包装响应可迭代对象,但不应使用。您不能使用类似文件的对象
tell()或write()方法。这样做会引发异常。
HttpResponseBase基类在HttpResponse和StreamingHttpResponse之间是通用的。
属性¶
- StreamingHttpResponse.streaming_content[source]¶
响应内容的迭代器,根据
HttpResponse.charset进行字节字符串编码。
- StreamingHttpResponse.status_code¶
响应的HTTP 状态代码。
除非显式设置
reason_phrase,否则在构造函数外部修改status_code的值也会修改reason_phrase的值。
- StreamingHttpResponse.reason_phrase¶
响应的 HTTP 原因短语。它使用HTTP 标准的默认原因短语。
除非显式设置,否则
reason_phrase由status_code的值确定。
- StreamingHttpResponse.streaming¶
这始终为
True。
- StreamingHttpResponse.is_async¶
布尔值,指示
StreamingHttpResponse.streaming_content是否为异步迭代器。这对于需要包装
StreamingHttpResponse.streaming_content的中间件很有用。
处理断开连接¶
如果客户端在流式传输响应期间断开连接,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]¶
FileResponse是StreamingHttpResponse的一个子类,针对二进制文件进行了优化。如果 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标头时,会自动设置该标头。当可以从
filename或open_file的名称中推测出Content-Type标头时,会自动设置该标头。
FileResponse 接受任何具有二进制内容的类文件对象,例如以二进制模式打开的文件,如下所示
>>> from django.http import FileResponse
>>> response = FileResponse(open("myfile.png", "rb"))
文件将自动关闭,因此不要使用上下文管理器打开它。
在 ASGI 下使用
Python 的文件 API 是同步的。这意味着必须完全使用文件才能在 ASGI 下提供服务。
为了异步地流式传输文件,您需要使用提供异步文件 API 的第三方包,例如 aiofiles。
方法¶
HttpResponseBase 类¶
HttpResponseBase 类是所有 Django 响应的通用类。不应直接使用它来创建响应,但它对于类型检查很有用。