请求和响应对象¶
快速概述¶
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_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。
- 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 解析器,例如ElementTree
import 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 标准库中的
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。
- 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 响应的通用类。不应直接使用它来创建响应,但它对于类型检查很有用。