• django-response对象


      回顾 HTTP 协议的通信核心,无非就是请求报文和响应报文之间的交互。而请求报文由客户端生成,也就是用户的浏览器;响应报文则由服务器生成,作为web应用的开发者,大多数工作就是构造一个合适的响应报文。在 django 中,请求报文已经被封装成了 HttpRequest 对象,该对象的创建是自动的,且会传递给视图函数作为第一个参数。而 HttpResponse 对象则需要 web 开发者自己创建,一般在视图函数中 return 回去。下面我们就来看看 HttpResponse 对象的各种细节。

      首先,这个对象由 HttpResponse 类创建,这个类位于 django.http 模块中,所以在使用的时候还先从模块中导入这个类。

    例如:

    from django.http import HttpResponse

      然后,我们需要知道传递什么参数,这个时候先看看其构造函数是怎么样的。

     HttpResponse.__init__(content='', content_type=None, status=200, reason=None, charset=None) 

      content:可以是一个迭代器或字符串。如果是一个迭代器,HttpResponse 将立即处理这个迭代器, 把它的内容转成字符串,并丢弃这个迭代器。如果你需要从迭代器到客户端的数据响应以数据流的形式, 你必须用 StreamingHttpResponse 类代替;如果是一个字符串(迭代器处理后的或手动传入的),那么这个字符串将作为相应报文的主体内容,也就是说如果是一个 http 文档,那么这个文档将会放入响应报文的主体中,最后在浏览器中显示,这也是最为常用的方式之一。

      content_type:用于指定 MIME 类型和编码,例如:“text/html; charset=utf-8”。客户端需要知道主体是什么类型的资源,才能调用相应的插件或内置的程序去处理。如果不传入,也就是为 None 时,将使用 DEFAULT_CONTENT_TYPE 的值来指定 MIME 类型,这个值默认为:'text/html';使用 DEFAULT_CHARSET 的值来指定文件编码,默认为:'utf-8'。

      status:响应状态码,200代表成功,一般不需要改变,除非有特殊要求。

      reason:原因短语,也就是 200 ok 中的 ‘ok’,因为客户端是根据状态码来判断响应是否成功的,所以 reason 的影响几乎为 0 ,只是对人的提醒而已。如果没有指定, 则使用默认响应短语。也就是 200 就对应于 ok,404 就对应于 not found。

      charset:在response中被编码的字符集。如果没有给定(也就是为None),将会从 content_type 中提取,如果提取不成功, 那么 DEFAULT_CHARSET 的设定将被使用。

    同样的,我们可以使用相关的属性去查看这些值:

     HttpResponse.content :表示内容的字符串,对应于我们传入的 content 参数的值。

     HttpResponse.charset :一个表示编码的字符串,对应于 charset 参数,如果实例化的时候没有给定,将从 content_type 中解析出来,如果解析失败,将使用 DEFAULT_CHARSET 的值。

     HttpResponse.status_code :表示响应的状态码。在 1.9 中除非 reason_phrase 属性被显式的设置,否则在构造函数外修改状态码时,也会修改 reason_phrase 属性。也就是说,当我们在创建实例的时候,并没有设置 reason ,原来的状态码是 200 ,当我们在构造器外修改这个属性的时候,如修改成 404,那么 reason_phrase 属性就变成对应的 not found。

     HttpResponse.reason_phrase :表示响应的原因短语,对应于 reason 参数。在1.9中 reason_phrase 不再默认为全部大写字母。现在使用 HTTP 标准的默认原因短语。除非显式设置,reason_phrase 由status_code 的值的确定。

     HttpResponse.streaming :这个选项总是 False。由于这个属性的存在,使得中间件(middleware)能够区别对待流式 response 和常规 response 。

     HttpResponse.closed :如果响应已关闭,则是 True 的。

     HttpResponse.__setitem__(header, value) 

     由给定的首部名称和值设定相应的报文首部。 header 和 value 都应该是字符串类型。

     HttpResponse.__delitem__(header) 

    根据给定的首部名称来删除报文中的首部。如果对应的首部不存在将沉默地(不引发异常)失败。不区分大小写。

     HttpResponse.__getitem__(header) 

    根据首部名称返回其值。不区分大小写。

     HttpResponse.has_header(header) 

    通过检查首部中是否有给定的首部名称(不区分大小写),来返回 True 或 False 。

     HttpResponse.setdefault(header, value) 

    设置一个首部,除非该首部 header 已经存在了。

    另外,我们还可以使用类字典的方法来设置首部,例如:

    >>> response = HttpResponse()
    >>> response['Age'] = 120
    >>> del response['Age']

    注意:当调用 del 去删除的首部不存在时,会引发 KeyError 异常。 

      但是,当我们设定 Cache-Control 首部和 Vary 首部时,推荐使用 patch_cache_control() 和 patch_vary_headers()方法,可以从 django.utils.cache 中导入它们。因为这两个首部通常有多个值,这些值都要逗号隔开。"patch" 方法可以确保这些值,例如由中间件添加的值不会被改变。而字典形式添加的,同名键的不同值会发生冲突,只有最后一个值有效。

      另外,虽然标准的 HTTP 报文中要求首部的每一行都要使用换行符隔开,但是 django 已经帮我们做了这些,所以我们不用重复的添加换行符了,否则会触发 BadHeaderError 异常。

     HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False) 

      设置一个Cookie。参数与Python 标准库中的 Morsel Cookie 对象相同。

      key:键名,字符串形式。

      value:对应的值,字符串形式。

      max_age:cookie 过期的相对时间,单位是秒。如果为None,则当浏览器关闭的时候过期。如果设置了 max_age 而没有设置 expires,则 expires 将根据 max_age 的值计算出来。

      expires:设置 cookie 过期的绝对时间。应该是一个 UTC "Wdy, DD-Mon-YY HH:MM:SS GMT" 格式的字符串,或者一个 datetime.datetime 对象。如果 expires 是一个datetime 对象,则 max_age 会通过计算得到。

      path:一个字符串,表示客户端回送 cookie 的路径,如果为‘/’,则表示该域名下的所以路径都将回送 cookie,如果是‘/blog/’;则在访问‘/blog/abc’或者‘/blog/def’等,所有包含该前缀的路径时,客户端都会回送 cookie。

      domain:cookie有效的域。例如,其值为‘.scolia.com’时,那么在访问 www.scolia.com 或者 test.scolia.com 之类的时,都会回送 cookie ,当然通常会和 path 配合在一起使用。根据 HTTP 协议的要求,这个值必要要两到三个句点,从而防止出现 ‘.com’、‘.edu’、‘va.us’等形式的域名。当域为高层域时,只要两个句点就可以了,而高层域包括:.com、.edu、.net、.org、.gov、.mil、.int、.biz、.info、.name、 .museum、.coop、.aero、和.pro。其他的域则需要至少三个。

      secure:当其为 True 时,表示只要在 https 连接的情况下才会回送cookie

      httponly:当其为 True 时,JavaScript 等就不能访问对应的cookie了。当然这个标记并不是cookie标准中的,但目前市面上常用的浏览器都支持。灵活使用可以提供数据的安全性。

    注意:

      RFC 2109 和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=True) 

      与 set_cookie() 类似,但是在设置之前将用密钥签名,也就是常说的加盐处理。通常与 HttpRequest.get_signed_cookie() 一起使用。你可以使用可选的 salt 参数来增加密钥强度,但需要记住在调用 HttpRequest.get_signed_cookie() 时,也要把使用的 salt 参数传入,用于解密。

     HttpResponse.delete_cookie(key, path='/', domain=None) 

      在cookie中删除指定的 key 及其对应的 value。如果 key 不存在则什么也不发生,也就是不会引发异常。

      由于 Cookie 的工作方式,path 和 domain 应该与 set_cookie() 中使用的值相同 —— 否则 Cookie 不会删掉。

     HttpResponse.write(content) 

      将 content 写到报文的主体中,这使得 HttpResponse 的实例类似于文件对象。

      类似的还有:

       HttpResponse.flush() :将缓存区的内容写入到报文中

       HttpResponse.tell() :移动文件中的操作指针

     HttpResponse.getvalue() 

      从 HttpResponse.content 中返回其值。这使 HttpResponse 的实例类似于数据流对象。

     HttpResponse.writable() 

      总是 True,表示其是可写的。这使 HttpResponse 的实例类似于数据流对象。

     HttpResponse.writelines(lines) 

      在内容中写入一行。不添加行分隔符。这使 HttpResponse 的实例类似于数据流对象。


    HttpResponse的子类

    Django包含了一系列的HttpResponse衍生类(子类),用来处理不同类型的HTTP 响应(response)。与 HttpResponse 相同, 这些衍生类(子类)存在于 django.http 之中。

     class HttpResponseRedirect 

      构造函数的第一个参数是必要的 — 用来重定向的地址。这些能够是完全特定的URL地址(比如,'http://www.yahoo.com/search/'),或者是一个不包含域名的绝对路径地址(例如, '/search/')。关于构造函数的其他参数,可以参见 HttpResponse注意!这个响应会返回一个302的HTTP状态码。

      url:一个只读属性,表示代表响应将会重定向的URL地址(相当于Location 首部信息)。

     

     class HttpResponsePermanentRedirect 

      与 HttpResponseRedirect 一样,但是它会返回一个永久的重定向(HTTP状态码301)而不是一个“found”重定向(状态码302)。

     class HttpResponseNotModified 

      构造函数不会有任何的参数,并且不应该向这个响应(response)中加入内容(content)。使用这个意味着资源在用户最后一次请求之后,没有修改过(状态码304)。

     class HttpResponseBadRequest 

      与HttpResponse的行为类似,但是使用了一个400的状态码。表示一个错误的请求。

     class HttpResponseNotFound 

      与HttpResponse的行为类似,但是使用了一个404的状态码。表示资源没有找到。

     

     class HttpResponseForbidden 

      与HttpResponse的行为类似,但是使用了一个403的状态码。表示用户无权访问。

     class HttpResponseNotAllowed 

      与HttpResponse的行为类似,但是使用了一个405的状态码。表示请求的方法不被允许。 构造函数的第一个参数是必须的:一个允许使用的方法构成的列表(例如,['GET', 'POST'])。也就是说不在列表中的方法就是不被运行的方法。

     class HttpResponseGone 

      与HttpResponse的行为类似,但是使用了一个410的状态码。表示服务器曾经拥有过此资源。主要是在 web 站点进行维护的时候,通知客户端。

      

     class HttpResponseServerError 

      与HttpResponse的行为类似,但是使用了一个500的状态码。表示服务器内部错误。

    注意:如果一个自定义的 HttpResponse 的子类实现了 render 方法,那么 django 会将其当作一个 SimpleTemplateResponse。 render 方法必须返回一个有效的响应对象。


    JsonResponse

      json是目前常用的一种数据格式,有时候我们需要返回一个json格式的数据,而 JsonResponse 提供了一个快捷的方法。

      它是 HttpResponse 的一个子类,用来帮助用户创建JSON 编码的响应。它从父类继承大部分行为,下面看起构造函数:

     class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)  

      data:应该传递一个标准的 python 字典给它,它将其转换成 json 格式的数据。

      encoder:默认为 django.core.serializers.json.DjangoJSONEncoder,用于序列化data。关于这个序列化的更多信息参见JSON 序列化

      safe : 默认为True如果设置为False,可以传递任何对象进行序列化(否则,只允许dict 实例)。如果safe 为True,而第一个参数传递的不是dict 对象,将抛出一个TypeError

    另外:它的默认 Content-Type 头部设置为application/json。

      json_dumps_params:在1.9版本中新增,可以传递一个python标准的 json 库中,json.dump() 方法处理后的对象给它,用于生成一个响应。

    用法:

    典型的用法如下:

    >>> from django.http import JsonResponse
    >>> response = JsonResponse({'foo': 'bar'})
    >>> response.content
    '{"foo": "bar"}'

     

    序列化非字典对象:

    若要序列化非dict 对象,你必须设置safe 参数为False

    >>> response = JsonResponse([1, 2, 3], safe=False)

    如果不传递safe=False,将抛出一个TypeError

    注意:

    在EcmaScript 第5版之前,这可能会使JavaScript Array 构造函数崩溃。出于这个原因,Django 默认不允许传递非字典对象给JsonResponse 构造函数。然而,现代的大部分浏览器都已经实现EcmaScript 5,它删除了这种攻击性的数组。所以可以不用关注这个安全预防措施。

    修改默认的JSON 编码器:

    如果你需要使用不同的JSON 编码器类,你可以传递encoder 参数给构造函数:

    >>> response = JsonResponse(data, encoder=MyJSONEncoder)

    StreamingHttpResponse 

     class StreamingHttpResponse 

      StreamingHttpResponse类被用来从Django流式化一个响应(response)到浏览器。当生产的响应太长或者占用太多的内存的时候,你可能会使用到它。例如,它对于生成大型CSV文件非常有用。

    性能方面的考虑:

      django是为了短链接而设计的,也就是说每次响应完毕之后都会断开连接。流式响应将会为整个响应期协同工作进程。这可能导致性能变差。

      总的来说,你需要将代价高的任务移除 请求—响应 的循环,而不是求助于流式响应。

    StreamingHttpResponse 不是 HttpResponse 的衍生类(子类),因为它实现了完全不同的应用程序接口(API)。尽管如此,除了以下的几个明显不同的地方,其他几乎完全相同:

    • 应该提供一个迭代器给它,这个迭代器生成出字符串将用来构成内容(content)
    • 你不能直接访问它的内容(content),除非迭代响应对象本身。这只在响应被返回到客户端的时候发生。
    • 它没有 content 属性。取而代之的是,它有一个 streaming_content 属性。
    • 你不能使用类似文件对象的tell()或者 write() 方法。那么做会抛出一个异常

    StreamingHttpResponse 应该只在下面的情况下使用:请求是独立的,并且整个内容是不能重复的,在发生给客户端之前。因为其内容(content)是不能访问的,所以很多中间件是无法正常工作的。例如:ETag 和 Content- Length 首部就不能在流式相应中生成。

    属性:

     StreamingHttpResponse.streaming_content 

      一个迭代器,包含内容字符串。

     StreamingHttpResponse.status_code 

      响应的状态码

     StreamingHttpResponse.reason_phrase 

      响应的原因短语

     StreamingHttpResponse.streaming 

      总是True,表示其是一个流式响应。


    FileResponse 

     class FileResponse 

      FileResponseStreamingHttpResponse的衍生类(子类),为二进制文件做了优化。如果 wsgi server 来提供,则使用了wsgi.file_wrapper ,否则将会流式化一个文件为一些小块。

    FileResponse 需要通过二进制模式打开文件,如下:

    >>> from django.http import FileResponse
    >>> response = FileResponse(open('myfile.png', 'rb'))
  • 相关阅读:
    WebView Android 调用js且须要获取返回结果
    推荐系统--揭开推荐的神奇面纱
    回调函数
    对CAB文件进行数字签名
    adodb.RecordSet的属性和方法
    Code Review中的几个提示
    Linux下find命令具体解释
    html5中关于input使用方法的改变
    关于 ioctl 的 FIONREAD 參数
    Grant的时候报错的解决:Access denied for user 'root'@'localhost' (using password: YES)
  • 原文地址:https://www.cnblogs.com/scolia/p/5635546.html
Copyright © 2020-2023  润新知