请求和响应对象 — Django 文档
请求和响应对象
快速概述
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
中读取。 参见 HttpRequest.read()。
- HttpRequest.path
表示请求页面的完整路径的字符串,不包括方案或域。
示例:
"/music/bands/the_beatles/"
- HttpRequest.path_info
在某些 Web 服务器配置下,主机名后面的 URL 部分被拆分为脚本前缀部分和路径信息部分。
path_info
属性始终包含路径的路径信息部分,无论使用的是什么 Web 服务器。 使用它代替 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
,这意味着使用 :setting:`DEFAULT_CHARSET` 设置)。 您可以写入此属性以更改访问表单数据时使用的编码。 任何后续属性访问(例如从 GET 或 POST 读取)都将使用新的encoding
值。 如果您知道表单数据不在 :setting:`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
不 包括文件上传信息。 请参阅 文件 。
- 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
。请注意,:djadmin:`runserver` 删除了名称中带有下划线的所有标题,因此您不会在
META
中看到它们。 这可以防止基于下划线和破折号之间的歧义的标题欺骗,两者都被规范化为 WSGI 环境变量中的下划线。 它与 Nginx 和 Apache 2.4+ 等 Web 服务器的行为相匹配。HttpRequest.headers 是一种更简单的方法来访问所有带 HTTP 前缀的头,加上
CONTENT_LENGTH
和CONTENT_TYPE
。
- HttpRequest.headers
2.2 版中的新功能。
一个不区分大小写的类似 dict 的对象,它提供对请求中所有带 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)
- HttpRequest.resolver_match
- ResolverMatch 的实例,表示解析的 URL。 此属性仅在 URL 解析发生后设置,这意味着它在所有视图中可用,但在 URL 解析发生之前执行的中间件中不可用(尽管您可以在 process_view() 中使用它)。
应用程序代码设置的属性
Django 本身不会设置这些属性,但如果您的应用程序设置了这些属性,则会使用它们。
- HttpRequest.current_app
- :ttag:`url` 模板标签将使用它的值作为 reverse() 的
current_app
参数。
- HttpRequest.urlconf
这将用作当前请求的根 URLconf,覆盖 :setting:`ROOT_URLCONF` 设置。 有关详细信息,请参阅 Django 如何处理请求 。
urlconf
可以设置为None
以恢复以前中间件所做的任何更改并返回使用 :setting:`ROOT_URLCONF`。
中间件设置的属性
Django 的 contrib 应用程序中包含的一些中间件在请求上设置属性。 如果您在请求中没有看到该属性,请确保在 :setting:`MIDDLEWARE` 中列出了适当的中间件类。
- HttpRequest.session
- 来自 SessionMiddleware:一个可读可写的、类似字典的对象,代表当前会话。
- HttpRequest.site
- 来自 CurrentSiteMiddleware:Site 或 RequestSite 的实例,由 get_current_site() 返回,代表当前站点。
- HttpRequest.user
来自 AuthenticationMiddleware:代表当前登录用户的 :setting:`AUTH_USER_MODEL` 实例。 如果用户当前未登录,
user
将设置为 AnonymousUser 的实例。 您可以使用 is_authenticated 区分它们,如下所示:if request.user.is_authenticated: ... # Do something for logged-in users. else: ... # Do something for anonymous users.
方法
- HttpRequest.get_host()
使用来自
HTTP_X_FORWARDED_HOST
(如果 :setting:`USE_X_FORWARDED_HOST` 已启用)和HTTP_HOST
标头中的信息返回请求的原始主机,按该顺序。 如果它们不提供值,则该方法使用SERVER_NAME
和SERVER_PORT
的组合,详见 PEP 3333。示例:
"127.0.0.1:8000"
笔记
当主机位于多个代理之后时,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
(如果 :setting:`USE_X_FORWARDED_PORT` 已启用)和SERVER_PORT
META
变量的信息返回请求的发起端口,在那个命令。
- HttpRequest.get_full_path()
返回
path
以及附加的查询字符串(如果适用)。示例:
"/music/bands/the_beatles/?print=true"
- HttpRequest.get_full_path_info()
2.1 版中的新功能。
类似于 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.is_ajax()
如果请求是通过
XMLHttpRequest
发出的,则通过检查字符串'XMLHttpRequest'
的HTTP_X_REQUESTED_WITH
标头,返回True
。 大多数现代 JavaScript 库都会发送此标头。 如果您编写自己的XMLHttpRequest
调用(在浏览器端),如果您希望is_ajax()
工作,则必须手动设置此标头。如果响应因是否通过 AJAX 请求而有所不同,并且您正在使用某种形式的缓存,例如 Django 的 缓存中间件 ,您应该使用 vary_on_headers('X-Requested-With ') 以便正确缓存响应。
- 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
,则默认为 :setting:`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)
- 返回具有请求键的数据列表。 如果键不存在且未提供默认值,则返回一个空列表。 除非提供的默认值不是列表,否则保证返回列表。
- 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 模块中。
如何使用
传入字符串
典型用法是将页面内容作为字符串或字节串传递给 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
作为类文件对象:
>>> 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 类。
设置头字段
要在响应中设置或删除标头字段,请将其视为字典:
>>> response = HttpResponse()
>>> response['Age'] = 120
>>> del response['Age']
请注意,与字典不同,如果标题字段不存在, del
不会引发 KeyError
。
要设置 Cache-Control
和 Vary
标头字段,建议使用 django 中的 patch_cache_control() 和 patch_vary_headers() 方法.utils.cache,因为这些字段可以有多个逗号分隔的值。 “补丁”方法确保其他值,例如 由中间件添加,不会被删除。
HTTP 标头字段不能包含换行符。 尝试设置包含换行符(CR 或 LF)的标头字段将引发 BadHeaderError
告诉浏览器将响应作为文件附件处理
要告诉浏览器将响应视为文件附件,请使用 content_type
参数并设置 Content-Disposition
标头。 例如,您可以通过以下方式返回 Microsoft Excel 电子表格:
>>> response = HttpResponse(my_data, content_type='application/vnd.ms-excel')
>>> response['Content-Disposition'] = 'attachment; filename="foo.xls"'
Content-Disposition
标头没有任何特定于 Django 的内容,但很容易忘记语法,因此我们将其包含在此处。
属性
- HttpResponse.content
- 一个代表内容的字节字符串,必要时由字符串编码。
- HttpResponse.charset
- 一个字符串,表示将在其中编码响应的字符集。 如果在
HttpResponse
实例化时间没有给出,它将从content_type
中提取,如果不成功,将使用 :setting:`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)
使用给定的页面内容和内容类型实例化
HttpResponse
对象。content
最常见的是迭代器、字节串或字符串。 其他类型将通过对其字符串表示进行编码来转换为字节串。 迭代器应该返回字符串或字节串,它们将连接在一起形成响应的内容。content_type
是由字符集编码可选完成的 MIME 类型,用于填充 HTTPContent-Type
标头。 如果不指定,则由 :setting:`DEFAULT_CONTENT_TYPE` 和 :setting:`DEFAULT_CHARSET` 设置组成,默认为:“text/html; 字符集=utf-8”。status
是响应的 HTTP 状态代码 。 您可以将 Python 的http.HTTPStatus
用于有意义的别名,例如HTTPStatus.NO_CONTENT
。reason
是 HTTP 响应短语。 如果未提供,将使用默认短语。charset
是响应将被编码的字符集。 如果没有给出,它将从content_type
中提取,如果不成功,将使用 :setting:`DEFAULT_CHARSET` 设置。
- HttpResponse.__setitem__(header, value)
- 将给定的标头名称设置为给定的值。
header
和value
都应该是字符串。
- HttpResponse.__delitem__(header)
- 删除具有给定名称的标题。 如果标头不存在,则静默失败。 不区分大小写。
- HttpResponse.__getitem__(header)
- 返回给定标题名称的值。 不区分大小写。
- HttpResponse.has_header(header)
- 基于对具有给定名称的标头的不区分大小写检查,返回
True
或False
。
- HttpResponse.setdefault(header, value)
- 设置响应头,除非它已经被设置。
- HttpResponse.set_cookie(key, value=, max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False, samesite=None)
设置一个 cookie。 参数与 Python 标准库中的
Morsel
cookie 对象相同。max_age
应该是秒数,或者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 只能被设置它的域读取。如果您想阻止客户端 JavaScript 访问 cookie,请使用
httponly=True
。HttpOnly 是包含在 Set-Cookie HTTP 响应头中的标志。 它是用于 cookie 的 RFC 6265 标准的一部分,并且是降低客户端脚本访问受保护 cookie 数据风险的有用方法。
使用
samesite='Strict'
或samesite='Lax'
告诉浏览器在执行跨域请求时不要发送此 cookie。 SameSite 并非所有浏览器都支持,因此它不是 Django 的 CSRF 保护的替代品,而是一种深度防御措施。
2.1 版更改: 添加了
samesite
参数。警告
RFC 6265 声明用户代理应该支持至少 4096 字节的 cookie。 对于许多浏览器,这也是最大尺寸。 如果尝试存储超过 4096 字节的 cookie,Django 不会引发异常,但许多浏览器不会正确设置 cookie。
- HttpResponse.set_signed_cookie(key, value, salt=, max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False, samesite=None)
- 像 set_cookie(),但是 cryptographic signature 在设置 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 可能不会被删除。在 2.2.15 版更改: 添加了
samesite
参数。
- 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 包含许多 HttpResponse
子类,用于处理不同类型的 HTTP 响应。 与 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)。
- class HttpResponseNotModified
- 构造函数不接受任何参数,也不应向此响应添加任何内容。 使用它来指定自用户上次请求(状态代码 304)以来没有修改过的页面。
- class HttpResponseBadRequest
- 行为就像 HttpResponse 但使用 400 状态代码。
- class HttpResponseNotFound
- 行为就像 HttpResponse 但使用 404 状态代码。
- class HttpResponseForbidden
- 行为就像 HttpResponse 但使用 403 状态代码。
- class HttpResponseNotAllowed
- 类似于 HttpResponse,但使用 405 状态代码。 构造函数的第一个参数是必需的:允许的方法列表(例如
['GET', 'POST']
)。
- class HttpResponseGone
- 行为就像 HttpResponse 但使用 410 状态代码。
- class 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 物体
- class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)
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
。
警告
在 第 5 版 ECMAScript 之前,有可能毒害 JavaScript Array
构造函数。 为此,Django 默认不允许将非 dict 对象传递给 JsonResponse 构造函数。 然而,大多数现代浏览器都实现了 EcmaScript 5,它消除了这种攻击向量。 因此,可以禁用此安全预防措施。
更改默认 JSON 编码器
如果您需要使用不同的 JSON 编码器类,您可以将 encoder
参数传递给构造函数方法:
>>> response = JsonResponse(data, encoder=MyJSONEncoder)
StreamingHttpResponse 物体
- class StreamingHttpResponse
StreamingHttpResponse 类用于将响应从 Django 流式传输到浏览器。 如果生成响应时间太长或使用太多内存,您可能想要这样做。 例如,它对于 生成大型 CSV 文件 很有用。
性能注意事项
Django 是为短期请求而设计的。 流响应将在响应的整个持续时间内绑定一个工作进程。 这可能会导致性能不佳。
一般来说,你应该在请求响应周期之外执行昂贵的任务,而不是求助于流式响应。
StreamingHttpResponse 不是 HttpResponse 的子类,因为它的 API 略有不同。 但是,它几乎相同,但有以下显着差异:
- 应该给它一个迭代器,产生字节字符串作为内容。
- 您无法访问其内容,除非迭代响应对象本身。 这应该只在响应返回给客户端时发生。
- 它没有
content
属性。 相反,它具有 streaming_content 属性。 - 您不能使用类文件对象
tell()
或write()
方法。 这样做会引发异常。
StreamingHttpResponse 应该只在绝对需要在将数据传输到客户端之前不迭代整个内容的情况下使用。 由于内容无法访问,很多中间件无法正常工作。 例如,无法为流响应生成 ETag
和 Content-Length
标头。
属性
- 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
。
FileResponse 物体
- class FileResponse(open_file, as_attachment=False, filename=, **kwargs)
FileResponse 是针对二进制文件优化的 StreamingHttpResponse 的子类。 如果 wsgi 服务器提供,它使用 wsgi.file_wrapper,否则它将文件以小块的形式流出。
如果
as_attachment=True
,则设置Content-Disposition
标头,要求浏览器将文件作为下载提供给用户。如果
open_file
没有名称或open_file
的名称不合适,请使用filename
参数提供自定义文件名。 请注意,如果您传递一个类似文件的对象,例如io.BytesIO
,那么在将其传递给FileResponse
之前,您的任务是seek()
。Content-Length
、Content-Type
和Content-Disposition
标题在可以从open_file
的内容中猜出时自动设置。2.1 新功能: 增加了
as_attachment
和filename
关键字参数。 此外,FileResponse
设置Content
标头,如果它可以猜到的话。
FileResponse
接受任何具有二进制内容的类文件对象,例如以二进制模式打开的文件,如下所示:
>>> from django.http import FileResponse
>>> response = FileResponse(open('myfile.png', 'rb'))
该文件将自动关闭,因此不要使用上下文管理器打开它。
方法
- FileResponse.set_headers(open_file)
2.1 版中的新功能。
此方法在响应初始化期间自动调用,并根据
open_file
设置各种标头(Content-Length
、Content-Type
和Content-Disposition
)。