请求和响应对象 — Django 文档

来自菜鸟教程
Django/docs/2.2.x/ref/request-response
跳转至:导航、​搜索

请求和响应对象

快速概述

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

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

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


HttpRequest 物体

class HttpRequest

属性

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

HttpRequest.scheme
表示请求方案的字符串(通常为 httphttps)。
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` 设置)。 您可以写入此属性以更改访问表单数据时使用的编码。 任何后续属性访问(例如从 GETPOST 读取)都将使用新的 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=""> 中的 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 主机标头。

  • 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

请注意,:djadmin:`runserver` 删除了名称中带有下划线的所有标题,因此您不会在 META 中看到它们。 这可以防止基于下划线和破折号之间的歧义的标题欺骗,两者都被规范化为 WSGI 环境变量中的下划线。 它与 Nginx 和 Apache 2.4+ 等 Web 服务器的行为相匹配。

HttpRequest.headers 是一种更简单的方法来访问所有带 HTTP 前缀的头,加上 CONTENT_LENGTHCONTENT_TYPE

HttpRequest.headers

2.2 版中的新功能。

一个不区分大小写的类似 dict 的对象,它提供对请求中所有带 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)
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
来自 CurrentSiteMiddlewareSiteRequestSite 的实例,由 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_NAMESERVER_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() 值的任何其他中间件之前 - 例如,CommonMiddlewareCsrfViewMiddleware

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 对象中,GETPOST 属性是 django.http.QueryDict 的实例,这是一个类似字典的类,用于处理多个值同样的钥匙。 这是必要的,因为一些 HTML 表单元素,特别是 <select multiple>,为同一个键传递多个值。

在正常请求/响应周期中访问时,request.POSTrequest.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.POSTrequest.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()

返回 QueryDictdict 表示。 对于 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-ControlVary 标头字段,建议使用 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_phrasestatus_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 类型,用于填充 HTTP Content-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)
将给定的标头名称设置为给定的值。 headervalue 都应该是字符串。
HttpResponse.__delitem__(header)
删除具有给定名称的标题。 如果标头不存在,则静默失败。 不区分大小写。
HttpResponse.__getitem__(header)
返回给定标题名称的值。 不区分大小写。
HttpResponse.has_header(header)
基于对具有给定名称的标头的不区分大小写检查,返回 TrueFalse
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 对象。 如果 expiresdatetime 对象,则将计算 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 的工作方式,pathdomain 应该与您在 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 实例)。 如果 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

警告

第 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 应该只在绝对需要在将数据传输到客户端之前不迭代整个内容的情况下使用。 由于内容无法访问,很多中间件无法正常工作。 例如,无法为流响应生成 ETagContent-Length 标头。

属性

StreamingHttpResponse.streaming_content
响应内容的迭代器,字节串按照 HttpResponse.charset 编码。
StreamingHttpResponse.status_code

响应的 HTTP 状态代码

除非reason_phrase明确设置,在构造函数外修改status_code的值也会修改reason_phrase的值。

StreamingHttpResponse.reason_phrase

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

除非明确设置,否则 reason_phrasestatus_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-LengthContent-TypeContent-Disposition 标题在可以从 open_file 的内容中猜出时自动设置。

2.1 新功能: 增加了 as_attachmentfilename 关键字参数。 此外,FileResponse 设置 Content 标头,如果它可以猜到的话。

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

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

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

方法

FileResponse.set_headers(open_file)

2.1 版中的新功能。

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