请求和响应对象¶
快速概览¶
Django 使用请求和响应对象来传递系统状态。
当请求页面时,Django 会创建一个 HttpRequest
对象,其中包含有关请求的元数据。然后,Django 加载适当的视图,将 HttpRequest
作为第一个参数传递给视图函数。每个视图负责返回一个 HttpResponse
对象。
本文档说明了 HttpRequest
和 HttpResponse
对象的 API,它们在 django.http
模块中定义。
HttpRequest
对象¶
-
class
HttpRequest
¶
属性¶
除非另有说明,否则所有属性都应视为只读。
-
HttpRequest.
scheme
¶ 表示请求方案的字符串(通常为
http
或https
)。
-
HttpRequest.
body
¶ 原始 HTTP 请求正文作为字节串。这对于以不同于传统 HTML 表单的方式处理数据非常有用:二进制图像、XML 有效负载等。要处理传统表单数据,请使用
HttpRequest.POST
。您还可以使用文件类似接口通过
HttpRequest.read()
或HttpRequest.readline()
从HttpRequest
中读取。在使用任一 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
¶ 表示用于解码表单提交数据(或
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 主机标头。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
¶ 一个不区分大小写的类似字典的对象,它提供对请求中所有 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
¶ 表示已解析 URL 的
ResolverMatch
实例。此属性仅在 URL 解析完成后设置,这意味着它在所有视图中都可用,但在 URL 解析之前执行的中间件中不可用(不过,你可以在process_view()
中使用它)。
由应用程序代码设置的属性¶
Django 本身不会设置这些属性,但如果你的应用程序设置了这些属性,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()
方法执行相同操作,但可用于异步上下文。
方法¶
-
HttpRequest.
auser
()¶ - Django 5.0 中的新增功能。
来自
AuthenticationMiddleware
:协程。返回表示当前登录用户的AUTH_USER_MODEL
实例。如果用户当前未登录,auser
将返回AnonymousUser
实例。这类似于user
属性,但它适用于异步上下文。
-
HttpRequest.
get_host
()¶ 使用
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
()¶ 使用
HTTP_X_FORWARDED_PORT
(如果USE_X_FORWARDED_PORT
已启用)和SERVER_PORT
META
变量中的信息,按此顺序返回请求的原始端口。
-
HttpRequest.
get_full_path
()¶ 返回
path
,以及附加的查询字符串(如果适用)。示例:
"/music/bands/the_beatles/?print=true"
-
HttpRequest.
get_full_path_info
()¶ 与
get_full_path()
类似,但使用path_info
而不是path
。示例:
"/minfo/music/bands/the_beatles/?print=true"
-
HttpRequest.
build_absolute_uri
(location=None)¶ 返回
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)¶ 返回签名 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
()¶ 如果请求是安全的,则返回
True
;也就是说,如果它是通过 HTTPS 发出的。
-
HttpRequest.
accepts
(mime_type)¶ 如果请求
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)¶
-
HttpRequest.
readline
()¶
-
HttpRequest.
readlines
()¶
-
HttpRequest.
__iter__
()¶ 用于从
HttpRequest
实例读取的类文件接口实现方法。这使得以流式方式使用传入请求成为可能。一个常见的用例是使用迭代解析器处理大型 XML 有效负载,而无需在内存中构建整个 XML 树。鉴于此标准接口,
HttpRequest
实例可以直接传递给 XML 解析器,例如ElementTree
import xml.etree.ElementTree as ET for element in ET.iterparse(request): process(element)
QueryDict
对象¶
-
class
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)¶ 基于
query_string
实例化QueryDict
对象。>>> QueryDict("a=1&a=2&c=3") <QueryDict: {'a': ['1', '2'], 'c': ['3']}>
如果未传入
query_string
,则生成的QueryDict
将为空(它将没有键或值)。您遇到的大多数
QueryDict
,尤其是request.POST
和request.GET
中的那些,将是不可变的。如果您自己实例化一个,可以通过将mutable=True
传递给它的__init__()
来使其可变。用于设置键和值的字符串将从
encoding
转换为str
。如果未设置encoding
,则它默认为DEFAULT_CHARSET
。
-
classmethod
QueryDict.
fromkeys
(iterable, value='', mutable=False, encoding=None)¶ 使用
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)¶ 将给定的键设置为
[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)¶ 类似于
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
()¶ 使用
copy.deepcopy()
返回对象的副本。即使原件不可变,此副本也将是可变的。
-
QueryDict.
getlist
(key, default=None)¶ 返回请求键的数据列表。如果键不存在且
default
为None
,则返回一个空列表。除非提供的默认值不是列表,否则保证返回一个列表。
-
QueryDict.
setlist
(key, list_)¶ 将给定的键设置为
list_
(与__setitem__()
不同)。
-
QueryDict.
appendlist
(key, item)¶ 将一个项目追加到与键关联的内部列表中。
-
QueryDict.
setlistdefault
(key, default_list=None)¶ 与
setdefault()
类似,除了它采用一个值列表而不是一个单一值。
-
QueryDict.
lists
()¶ 与
items()
类似,除了它包括字典中每个成员的所有值(作为列表)。例如>>> q = QueryDict("a=1&a=2&a=3") >>> q.lists() [('a', ['1', '2', '3'])]
-
QueryDict.
pop
(key)¶ 返回给定键的值列表,并从字典中删除它们。如果键不存在,则引发
KeyError
。例如>>> q = QueryDict("a=1&a=2&a=3", mutable=True) >>> q.pop("a") ['1', '2', '3']
-
QueryDict.
popitem
()¶ 删除字典中的任意成员(因为没有排序概念),并返回一个包含键和该键的所有值列表的二元值元组。在空字典上调用时引发
KeyError
。例如>>> q = QueryDict("a=1&a=2&a=3", mutable=True) >>> q.popitem() ('a', ['1', '2', '3'])
-
QueryDict.
dict
()¶ 返回
QueryDict
的dict
表示形式。对于QueryDict
中的每个 (key, list) 对,dict
将具有 (key, item),其中 item 是列表的一个元素,使用与QueryDict.__getitem__()
相同的逻辑>>> q = QueryDict("a=1&a=3&a=5") >>> q.dict() {'a': '5'}
-
QueryDict.
urlencode
(safe=None)¶ 返回查询字符串格式的数据字符串。例如
>>> 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
¶
与由 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()
方法,因为这些字段可以具有多个以逗号分隔的值。这些“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.
content
¶ 一个字节串,表示内容,必要时从字符串编码。
-
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)¶ 使用给定的页面内容、内容类型和标头实例化
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
是一个dict
,用于响应的 HTTP 标头。
-
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 将只能由设置它的域读取。如果您希望仅在使用
https
方案发出请求时才将 cookie 发送到服务器,请使用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 之前,对 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)¶ 此方法使
HttpResponse
实例成为类似文件的对象。
-
HttpResponse.
flush
()¶ 此方法使
HttpResponse
实例成为类似文件的对象。
-
HttpResponse.
tell
()¶ 此方法使
HttpResponse
实例成为类似文件的对象。
-
HttpResponse.
getvalue
()¶ 返回
HttpResponse.content
的值。此方法使HttpResponse
实例成为类似流的对象。
-
HttpResponse.
readable
()¶ 始终
False
。此方法使HttpResponse
实例成为类似流的对象。
-
HttpResponse.
seekable
()¶ 始终
False
。此方法使HttpResponse
实例成为类似流的对象。
-
HttpResponse.
writable
()¶ 始终
True
。此方法使HttpResponse
实例成为类似流的对象。
-
HttpResponse.
writelines
(lines)¶ 将行列表写入响应。不添加行分隔符。此方法使
HttpResponse
实例成为类似流的对象。
HttpResponse
子类¶
Django 包含许多处理不同类型 HTTP 响应的 HttpResponse
子类。与 HttpResponse
一样,这些子类位于 django.http
中。
-
class
HttpResponseRedirect
¶ 构造函数的第一个参数是必需的 - 要重定向到的路径。这可以是完全限定的 URL(例如
'https://www.yahoo.com/search/'
),不带域名的绝对路径(例如'/search/'
),甚至可以是相对路径(例如'search/'
)。在最后一种情况下,客户端浏览器将根据当前路径自行重建完整的 URL。有关其他可选构造函数参数,请参见HttpResponse
。请注意,这会返回 HTTP 状态代码 302。-
url
¶ 此只读属性表示响应将重定向到的 URL(相当于
Location
响应头)。
-
-
class
HttpResponsePermanentRedirect
¶ 类似于
HttpResponseRedirect
,但它返回永久重定向(HTTP 状态代码 301),而不是“已找到”重定向(状态代码 302)。
-
类
HttpResponseNotModified
¶ 构造函数不接受任何参数,且不应向此响应添加内容。使用此来指定页面自用户上次请求后未修改(状态代码 304)。
-
类
HttpResponseBadRequest
¶ 行为就像
HttpResponse
,但使用 400 状态代码。
-
类
HttpResponseNotFound
¶ 行为就像
HttpResponse
,但使用 404 状态代码。
-
类
HttpResponseForbidden
¶ 行为就像
HttpResponse
,但使用 403 状态代码。
-
类
HttpResponseNotAllowed
¶ 类似
HttpResponse
,但使用 405 状态代码。构造函数的第一个参数是必需的:允许的方法列表(例如['GET', 'POST']
)。
-
类
HttpResponseGone
¶ 作用类似于
HttpResponse
,但使用 410 状态代码。
-
类
HttpResponseServerError
¶ 作用类似于
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
对象¶
-
类
JsonResponse
(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)¶ 一个
HttpResponse
子类,用于创建 JSON 编码的响应。它继承了其超类的多数行为,但有一些不同之处其默认的
Content-Type
标头设置为 application/json。第一个参数
data
应为dict
实例。如果safe
参数设置为False
(见下文),它可以是任何可 JSON 序列化的对象。默认情况下为
django.core.serializers.json.DjangoJSONEncoder
的encoder
将用于序列化数据。有关此序列化器的更多详细信息,请参阅 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 编码的响应中使用非 dict 对象。
警告
在 ECMAScript 的第 5 版 之前,可以破坏 JavaScript Array
构造函数。出于此原因,Django 默认情况下不允许将非 dict 对象传递给 JsonResponse
构造函数。但是,大多数现代浏览器都实现了 ECMAScript 5,它消除了此攻击媒介。因此,可以禁用此安全预防措施。
更改默认 JSON 编码器¶
如果需要使用不同的 JSON 编码器类,可以将 encoder
参数传递给构造函数方法
>>> response = JsonResponse(data, encoder=MyJSONEncoder)
StreamingHttpResponse
对象¶
-
class
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
¶ 响应内容的迭代器,字节串根据
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
¶ - Django 4.2 中的新增功能。
指示
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
对象¶
-
类
FileResponse
(open_file, as_attachment=False, filename='', **kwargs)¶ 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
类¶
-
class
HttpResponseBase
¶
HttpResponseBase
类适用于所有 Django 响应。不应将其用于直接创建响应,但它可用于类型检查。