django views视图
视图函数简称视图,本质上是一个简单的python函数,它接受web请求并且返回web响应;响应的内容可以是HTML网页、重定向、404错误、XML文档或图像等任何东西,但是,无论视图本身是个什么处理逻辑,最好都返回某种响应
视图函数的代码写在哪都无所谓,只要它在你的python目录下面,但是通常我们约定将视图放置在项目或应用程序目录中的名为views.py的文件中。
1、一个简单的视图
下面是一个返回当前日期和时间作为HTML文档的视图:
from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html)
让我们逐行分析一下上面的代码:
首先,从django.http模块导入了HttpResponse类,以及python的datetime库
接着,我们定义了current_datetime视图函数
每个视图函数都接收一个HttpRequest对象作为第一位置参数,一般取名为request,你可以取别的名字,但这不符合潜规则,最好不要那么做
视图函数的名称没有强制规则,但尽量不要和python及django内置的各种名称重名,并且尽量精确地反映出它的功能,比如这里的current_datetime
该视图返回一个HttpResponse对象,其中包含生成的HTML页面。
2、返回错误
在django中返回http错误代码是非常简单的;HttpResponse的许多子类对应着除了200(代表OK)以外的一些常用的http状态码。
为了标识一个错误,可以直接返回那些子类中的一个实例,而不是普通的HttpResponse,想下面这样:
from django.http import HttpResponse, HttpResponseNotFound def my_view(request): # ... if foo: return HttpResponseNotFound('<h1>Page not found</h1>') else: return HttpResponse('<h1>Page was found</h1>')
django为404错误提供了一个特化的子类HttpResponseNotFound;由于一些状态码不太常用,所以不是每个状态码都有一个特化的子类。
也可以向HttpResponse的构造器传递HTTP状态码,来创建你想要的任何状态码的返回类,像下面这样:
from django.http import HttpResponse def my_view(request): # ... # Return a "created" (201) response code. return HttpResponse(status=201)
关键是在返回中提供status=201参数,别的什么303之类的错误都可以参照上面的例子。
3、Http404异常
class django.http.Http404
这是一个django内置的异常类,可以在需要的地方弹出它,django会捕获它,并且带上HTTP404错误码返回你当前APP的标准错误页面或者自定义错误页面,像下面这样:
from django.http import Http404 from django.shortcuts import render from polls.models import Poll def detail(request, poll_id): try: p = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise Http404("Poll does not exist") return render(request, 'polls/detail.html', {'poll': p})
为了在django返回404时显示自定义的HTML,可以创建要给名为404.html的HTML模版,并将其放置在模版树的顶层,当DEBUG设置为False时,此模版将被自动使用,当DEBUG为True时,可以向Http404提供消息,它将显示在标准的内置404调试模版中,可以使用这些消息进行调试。
4、Django内置的快捷方法
django在django.shortcuts模块中,为我们提供了很多快捷方便的类和方法,它们都很重要,使用频率很高。
(1)render()
render(request,template_name,context=None,content_type=None,status=None,using=None)
结合一个给定的模版和一个给定的上下文字典,返回一个渲染后的HttpResponse对象。
必须参数:
- request:视图函数处理的当前请求,封装了请求头的所有数据,其实就是视图参数request
- template_name:要使用的模版的完整名称或者模版名称的列表,如果是一个列表,将使用其中能够查找到的第一个模版
可选参数:
- context:添加到模版上下文的一个数据字典,默认是一个空字典,可以将需要提供给模版的数据以字典的格式添加进去,这里有个小技巧,使用python内置的locals()方法,可以方便的将函数作用于内的所有变量一次性添加
- context_type:用于生成的文档的MIME类型,默认为DEFAULT_CONTENT_TYPE设置的值
- status:响应的状态码,默认为200
- using:用于加载模版使用的模版引擎的NAME
示例:
下面的示例将渲染模版myapp/index.html,MIME类型为application/xhtml+xml:
from django.shortcuts import render def my_view(request): # View code here... return render(request, 'myapp/index.html', { 'foo': 'bar', }, content_type='application/xhtml+xml')
与下面的示例效果一样:
from django.http import HttpResponse from django.template import loader def my_view(request): # View code here... t = loader.get_template('myapp/index.html') c = {'foo': 'bar'} return HttpResponse(t.render(c, request), content_type='application/xhtml+xml')
(2)redirect()
redirect(to,permanent=False,args,*kwargs)
根据传递进来的URL参数,返回HttpResponseRedirect
参数to可以是:
- 一个模型,将调用模型的get_absolute_url()函数,反向解析出目的url
- 视图名称,可能带有参数:reverse()将用于反向解析url
- 一个绝对的或相对的URL:将原封不动的作为重定向的目标位置
默认情况下是临时重定向,如果设置permanent=True将永久重定向。
示例:
调用对象的get_absolute_url()方法来重定向URL:
from django.shortcuts import redirect def my_view(request): ... object = MyModel.objects.get(...) return redirect(object)
传递视图名,使用reverse()方法反向解析url:
def my_view(request): ... return redirect('some-view-name', foo='bar')
重定向到硬编码的URL:
def my_view(request): ... return redirect('/some/url/')
也适用于完整的URL:
def my_view(request): ... return redirect('https://example.com/')
所有上述形式都接受permanent参数,如果设置为true将返回永久重定向:
def my_view(request): ... object = MyModel.objects.get(...) return redirect(object, permanent=True)
(3)get_object_or_404()
get_object_or_404(klass,*args,**kwargs)
这个方法非常有用,常用于查询模型对象,找到则进行下一步处理,如果未找到则给用户返回404页面
在后台,django其实是调用了模型管理器的get()方法,只是返回一个对象,不同的是,如果get()发生异常,会引发Http404异常,从而返回404页面,而不是模型的DoesNotExist异常。
必需参数:
klass:要获取的对象的model类名或者QuerySet等
**kwargs:查询的参数,格式应该可以被get()接受
示例:
从MyModel中使用主键1来获取对象:
from django.shortcuts import get_object_or_404 def my_view(request): my_object = get_object_or_404(MyModel, pk=1)
上面的例子同下面一样:
from django.http import Http404 def my_view(request): try: my_object = MyModel.objects.get(pk=1) except MyModel.DoesNotExist: raise Http404("No MyModel matches the given query.")
除了传递model名称,还可以传递一个QuerySet实例:
queryset = Book.objects.filter(title__startswith='M') get_object_or_404(queryset, pk=1)
上面的示例不够简洁,因为它等同于:
get_object_or_404(Book, title__startswith='M', pk=1)
但是如果你的queryset来自其他地方,它就会很有用了
还可以使用manager,如果你自定义了管理器,这将很有用:
get_object_or_404(Book.dahl_objects, title='Matilda')
还可以使用related managers:
author = Author.objects.get(name='Roald Dahl') get_object_or_404(author.book_set, title='Matilda')
与get()一样,如果找到多个对象将引发一个MultipleObjectsReturned异常。
(4)get_list_or_404()
get_list_or_404(klass,*args,**kwargs)
这其实就是get_object_or_404多值获取版本;在后台,返回一个给定模型管理器上的filer()的结果,并将结果映射为一个列表,如果结果为空则弹出Http404异常
必需参数:
klass:获取该列表的一个model、manager或QuerySet实例
**kwargs:查询的参数,格式应该可以被filter()接受
示例:
下面的示例从mymodel中获取所有发布出来的对象:
from django.shortcuts import get_list_or_404 def my_view(request): my_objects = get_list_or_404(MyModel, published=True)
上面的例子同下面一样:
from django.http import Http404 def my_view(request): my_objects = list(MyModel.objects.filter(published=True)) if not my_objects: raise Http404("No MyModel matches the given query.")
5、HttpRequest对象
每当一个用户请求发送过来,django将http数据包中的相关内容,打包成为一个HttpRequest对象,并传递给视图函数作为第一个位置参数,也就是reques,视图函数负责返回一个HttpResponse对象
HttpRequest和HttpResponse对象定义在django.http模块中
(1)属性
HttpRequest对象的大部分属性是只读的,除非特别注明
- HttpRequest.scheme:字符串类型,表示请求的协议种类,如:'http'或‘https’
- HttpRequest.body:bytes类型,表示原始HTTP请求的正文,它对于处理非HTML形式的数据非常有用,二进制图像、XML等,如果要处理常规的表单数据,应该使用HttpRequest.POST;还可以使用类似读写的方式从HttpRequest中读取数据,参见HttpRequest.read()
- HttpRequest.path:字符串类型,表示当前请求页面的完整路径,但是不包括协议名或域名;例如:“、music/bands/the_beatles”。这个属性常被用于我们进行某项操作时,如果不通过,返回用户先前浏览的页面
- HttpRequest.path_info:在某些web服务器配置下,主机名后的URL部分被分成脚本前缀部分和路径信息部分;path_info属性将始终包含路径信息部分,不论使用的web服务器是什么,使用它代替path可以让代码在测试和开发环境中更容易地切换。
- HttpRequest.method:字符串类型,表示请求使用的HTTP方法,默认为大写,像这样:
if request.method == 'GET': do_something() elif request.method == 'POST': do_something_else()
通过这个属性来判断请求的方法,然后根据请求的方法不同,在视图中执行不同的代码。
- HttpRequest.encoding:字符串类型,表示提交的数据的编码方式(如果为None则表示使用DEFAULT_CHARSET设置)。这个属性是可写的,可以通过修改它来修改表单数据的编码,任何随后的属性访问(如GET或POST)将使用新的编码方式
- HttpRequest.content_type:表示请求的MIME类型的字符串,从CONTENT_TYPE标头解析
- HttpRequest.content_params:包含在CONTENT_TYPE标题中的键、值参数字典
- HttpRequest.GET:一个类似于字典的对象,包含GET请求中的所有参数,详情参考QueryDict文档
- HttpRequest.POST:一个包含所有POST请求的参数,以及包含表单数据的字典,如果需要访问请求中的原始或非表单数据,可以使用HttpRequest.body属性;POST中不包含上传文件的数据。
- HttpRequest.COOKIES:包含所有Cookie信息的字典,键和值都为字符串,可以类似字典类型的方式,在cookie中读写数据,但是注意cookie是不安全的因此,不要写敏感重要的信息。
- HttpRequest.FILES:一个类似于字典的对象,包含所有上传的文件数据,FILES中的每个键为<input type='file' name="" />中的name属性值,FILES中的每个值是一个UploadedFile;要在Django助攻实现文件上传,就要靠这个属性;如果请求方法是POST且请求的<form>中带有enctype="multipart/form-data"属性,那么FILES将包含上传的文件的数据,否则FILES将为一个空的类似于字典的对象,属于被忽略,无用的情形。
- HttpRequest.META:包含所有HTTP头部信息的字典,可用的头部信息取决于客户端和服务器,下面是一些示例:
-
- CONTENT_LENGTH —— 请求正文的长度(以字符串计)。
- CONTENT_TYPE —— 请求正文的MIME类型。
- HTTP_ACCEPT —— 可接收的响应Content-Type。
- HTTP_ACCEPT_ENCODING —— 可接收的响应编码类型。
- HTTP_ACCEPT_LANGUAGE —— 可接收的响应语言种类。
- HTTP_HOST —— 客服端发送的Host头部。
- HTTP_REFERER —— Referring页面。
- HTTP_USER_AGENT —— 客户端的user-agent字符串。
- QUERY_STRING —— 查询字符串。
- REMOTE_ADDR —— 客户端的IP地址。想要获取客户端的ip信息,就在这里!
- REMOTE_HOST —— 客户端的主机名。
- REMOTE_USER —— 服务器认证后的用户,如果可用。
- REQUEST_METHOD —— 表示请求方法的字符串,例如"GET" 或"POST"。
- SERVER_NAME —— 服务器的主机名。
- SERVER_PORT —— 服务器的端口(字符串)
以上只是比较重要和常用的,还有很多未列出,从上面可以看到,除CONTENT_LENGTH和CONTENT_TYPE之外,请求中的任何HTTP头部键转换为META键时,都会将所有字母大写并将连接符替换为下划线最后加上HTTP_前缀,所以,一个叫做X-Bender的头部将转换成META中的HTTP_X_BENDER键。
- HttpRequest.resolver_match:代表一个已解析的URL的ResolverMatch实例
- HttpRequest.headers:Django 2.2中的新功能,一个不区分大小写的类似dict的对象,它提供对请求中所有HTTP加前缀的标题的访问,每个标题的名称在User-Agent显示是用标题-外壳进行样式化,你可以不区分大小写的访问标头:
{'Content-Length': '', 'Content-Type': 'text/plain', 'Host': '127.0.0.1:8000', 'Connection': 'keep-alive', 'Cache-Control': 'max-age=0', 'Upgrade-Insecure-Requests': '1', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate, sdch, br', 'Accept-Language': 'zh-CN,zh;q=0.8', 'Cookie': 'sessionid=rff2y86kaa57vpsihwgo5j72v11c4m0i; csrftoken=tPHBVfuGzw4lYSNuaWYEXvJa2oiXlCEZeStm9LSLNfxRKxRY0p6xvYnr0518LN0L'}
(2)可自定义的属性
- django不会自动设置下面这些属性,而是由你自己在应用程序中设置并使用它们:
- HttpRequest.current_app:表示当前APP的名字,URL模版标签将使用其值作为reverse()方法的current_app参数。
- HttpRequest.urlconf:设置当前请求的根URLconf,用于指定不同的URL路由进入口,这将覆盖settings中的ROOT_URLCONF设置,将它的值修改为None可以恢复使用ROOT_URLCONF设置
(3)由中间件设置的属性
django的contrib应用中包含的一些中间件会在请求上设置属性:
- HttpRequest.session:SessionMiddleware中间件,一个可读写的,类似字典的对象,表示当前会话,我们要保存用户状态,回话过程等等,靠的就是这个中间件和这个属性
- HttpRequest.site:CurrentSiteMiddleware中间件:get_current_site()方法返回的site或RequestSite的实例,代表当前站点是哪个;django是支持多站点的,如果你同时上线了多个站点,就需要为每个站点设置一个站点id
- HttpRequest.user:AuthenticationMiddleware中间件,表示当前登录的用户的AUTH_USER_MODEL的实例,这个模型是django内置的auth模块下的User模型,如果用户当前未登录,则user将被设置为AnonymousUser的实例,可以使用is_authenticated方法判断当前用户是否合法用户,如下:
if request.user.is_authenticated: ... # Do something for logged-in users. else: ... # Do something for anonymous users.
(4)方法
- HttpRequest.get_host():
根据HTTP_X_FORWARDED_HOST和HTTP_HOST头部信息获取请求的原始主机,如果这两个头部没有提供相应的值,则使用SERVER_NAME和SERVER_PORT,如:127.0.0.1:8000
注:当主机位于多个代理的后面,get_host()方法将会失败,解决办法之一是使用中间件重写代理的头部,如下示例:
from django.utils.deprecation import MiddlewareMixin class MultipleProxyMiddleware(MiddlewareMixin): FORWARDED_FOR_FIELDS = [ 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED_HOST', 'HTTP_X_FORWARDED_SERVER', ] def process_request(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()
- HttpRequest.get_port():使用META中HTTP_X_FORWARDED_PORT和SERVER_PORT的信息返回请求的始发端口
- HttpRequest.get_full_path():返回包含完整参数列表的path。例如:/music/bands/the_beatles/?print=true
- HttpRequest.build_absolute_uri(location):返回location的绝对URI形式;如果location没有提供,则使用request.get_full_path()的值;
例如:"https://example.com/music/bands/the_beatles/?print=true"
注:不鼓励在同一站点混合部署HTTP和HTTPS,如果需要将用户重定向到HTTPS,最好使用Web服务器将所有HTTP流量重定向到HTTPS。
- HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None):从已签名的Cookie中获取值,如果签名不合法则返回django.core.signing.BadSignature
可选参数salt用来为密码加盐,提高安全系数。 max_age参数用于检查Cookie对应的时间戳是否超时。
>>> 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():如果使用的是Https,则返回True,表示连接是安全的。
HttpRequest.is_ajax():如果请求是通过XMLHttpRequest生成的,则返回True;这个方法的作用就是判断,当前请求是否通过ajax机制发送过来的。
HttpRequest.read(size=None)
HttpRequest.readline()
HttpRequest.readlines()
HttpRequest.xreadlines()
HttpRequest.iter()
上面的几个方法都是从HttpRequest实例读取文件数据的方法。
可以将HttpRequest实例直接传递到XML解析器,例如ElementTree:
import xml.etree.ElementTree as ET for element in ET.iterparse(request): process(element)
6、QueryDict对象
在HttpRequest对象中,GET和POST属性都是一个django.http.QueryDict的实例。也就是说你可以按本文下面提供的方法操作request.POST和request.GET。
request.POST或request.GET的QueryDict都是不可变,只读的。如果要修改它,需要使用QueryDict.copy()方法,获取它的一个拷贝,然后在这个拷贝上进行修改操作。
(1)方法
QueryDict 实现了Python字典数据类型的所有标准方法,因为它是字典的子类。
不同之处在于下面:
QueryDict.init(query_string=None, mutable=False, encoding=None):QueryDict实例化方法。注意:QueryDict的键值是可以重复的
>>> QueryDict('a=1&a=2&c=3') <QueryDict: {'a': ['1', '2'], 'c': ['3']}>
如果需要实例化可以修改的对象,添加参数mutable=True
classmethod QueryDict.fromkeys(iterable, value='', mutable=False, encoding=None):
循环可迭代对象中的每个元素作为键值,并赋予同样的值。
>>> QueryDict.fromkeys(['a', 'a', 'b'], value='val') <QueryDict: {'a': ['val', 'val'], 'b': ['val']}>
QueryDict.__getitem__():返回给定键的值,如果键具有多个值,则返回最后一个值
QueryDict.__setitem__(ke,value):将给定键设置为value,只能在可变的QueryDict上调用
QueryDict.__contains__():判断给定键是否存在
QueryDict.get(ke,default=None):同__getitem__()相同,只是多个了默认值返回
QueryDict.setdefault(key,default=None):它在__setitem__()内部使用
QueryDict.update(other_dict):用新的QueryDict或字典更新当前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(),如果有重复项目,返回最近的一个:
>>> q = QueryDict('a=1&a=2&a=3') >>> list(q.items()) [('a', '3')]
QueryDict.values():类似dict.values(),但是只返回最近的值,如下:
>>> q = QueryDict('a=1&a=2&a=3') >>> list(q.values()) ['3']
QueryDict.copy():使用copy.deepcopy()返回QueryDict对象的副本,此副本是可变的
QueryDict.getlist(key,defautl=None):返回键对应的值的列表,如果该键不存在并且为提供默认值,则返回一个空列表
QueryDict.setlist(key,list_):为list_设置给定的键
QueryDict.appendlist(key,item):将键追加到内部与键相关联的列表中
QueryDict.setdefault(key,default=None):类似dict.setdefault(),为某个键设置默认值
QueryDict.lists():类似items(),只是它将其中的每个键的值作为列表放在一起,如下:
>>> q = QueryDict('a=1&a=2&a=3') >>> q.lists() [('a', ['1', '2', '3'])]
QueryDict.pop(key):返回给定键的值的列表,并从QueryDict中移除该值,如键不存在则引发异常
>>> q = QueryDict('a=1&a=2&a=3', mutable=True) >>> q.pop('a') ['1', '2', '3']
QueryDict.popitem():删除QueryDict任意一个键,并返回二值元组,包含键和键的所有值的列表,在一个空的字典上调用时将引发KeyErro,如下:
>>> q = QueryDict('a=1&a=2&a=3', mutable=True) >>> q.popitem() ('a', ['1', '2', '3'])
QueryDict.dict():将QueryDict转换为python字典数据类型,并返回该字典,如果出现重复的键,则将所有的值打包成一个列表,改为新字典中键的值
>>> q = QueryDict('a=1&a=3&a=5') >>> q.dict() {'a': '5'}
QueryDict.urlencode(safe=Noen):为已编码的格式返回数据字符串:
>>> 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/'
7、HttpResponse对象
HttpResponse类定义在django.http模块中
HttpRequest对象由django自动创建,而HttpResponse对象则由程序员手动创建,我们编写的每个视图都要实例化、填充和返回一个HttpResponse对象,也就是函数的return值。
(1)使用方法
传递字符串:
最简单的方式his传递一个字符串作为页面的内容到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用作类文件对象,使用write()方法不断往里增加内容:
>>> response = HttpResponse() >>> response.write("<p>Here's the text of the Web page.</p>") >>> response.write("<p>Here's another paragraph.</p>")
传递可迭代对象:
HttpResponse会立即处理迭代器,并把它的内容存成字符串,最后废弃这个迭代器,比如文件在读取后,会立刻调用close()方法,关闭文件
设置头部字段:
可以把HttpResponse对象当作一个字典一样,在其中增加和删除头部字段:
>>> response = HttpResponse() >>> response['Age'] = 120 >>> del response['Age']
注意!与字典不同的是,如果要删除的头部字段如果不存在,del不会抛出KeyError异常。
HTTP的头部字段中不能包含换行。所以如果我们提供的头部字段值包含换行符(CR或者LF),将会抛出BadHeaderError异常
告诉浏览器将响应视为文件附件:
让浏览器以文件附件的形式处理响应,需要声明content_type类型和设置Content-Disposition头信息,给浏览器返回一个微软电子表格:
>>> response = HttpResponse(my_data, content_type='application/vnd.ms-excel') >>> response['Content-Disposition'] = 'attachment; filename="foo.xls"'
(2)属性
HttpResponse.content:响应的内容,bytes类型
HttpResponse.charset:编码的字符集,如果没指定,将会从content_type中解析出来
HttpResponse.status_code:响应的状态码,比如200
HttpResponse.reason_phrase:响应的HTTP原因短语,使用标准原因短语,除非明确设置,否则reason_phrase由status_code的值决定
HttpResponse.streaming:这个属性的值总是False,由于这个属性的存在,使得中间件能够区别对待流式响应和常规响应
HttpResponse.closed:如果响应已关闭,那么这个属性的值为True
(3)方法
HttpResponse.init(content='',content_type=None,status=200,reason=None,charset=None):响应的实例化方法,使用content参数和content_type实例化一个HttpResponse对象;content应该是一个迭代器或者字符串,如果是迭代器,这个迭代器返回的应是字符串,并且这些字符串连接起来形成response的内容,如果不是迭代器或者字符串,那么在其被接收的时候将转换成字符串。
content_type是可选的,用于填充HTTP的content_type头部,如果未指定,默认情况下由DEFAULT_CONTENT_TYPE和DEFAULT_CHARSET设置成:text/html;charset=utf-8
status是响应的状态码,resaon是HTTP响应短语,charset是编码方式
HttpResponse.has_header(header):检查头部中是否有给定的名称(不区分大小写),返回true或false
HttpResponse.__setitem__(header,value):设置标头
HttpResponse.__delitem__(header):删除标头
HttpResponse.__getitem__(header):查看标头
HttpResponse.setdefault(header,value):设置一个头部,除非该头部已经设置过了
HttpResponse.set_cookie(key,value='',max_age=None,expires=None,path='/',domain=None,secure=None,httponly=False):设置一个cookie,参数与python标准库中的Morsel.Cookie对象相同;max_age为生存周期以秒为单位;expires为到期时间;domain用于设置跨域的cookie
如果你想阻止客户端的JavaScript访问cookie,可以设置httponly=True
HttpResponse.set_signed_cookie(key,value,salt='',max_age=None,expires=None,path='/',domain=None,secure=None,httponly=True):与set_cookie类似,但是在设置之前将对cookie进行加密签名,通常与HttpResponse.get_signed_cookie()一起使用
HttpResponse.delete_cookie(key,path='/',domain=None):删除cookie中指定的key,由于cookie工作方式,path和domain应该与set_cookie()使用的值相同,否则cookie不会删除
HttpResponse.write(content):将HttpResponse实例看作类似文件的对象,往里添加内容
HttpResponse.flush():清空HttpResponse实例的内容
HttpResponse.tell():将HttpResponse实例看作类似文件的对象,移动位置指针
HttpResponse.getvalue():返回HttpResponse的值,此方法将HttpResponse实例看作是一个类似流的对象
HttpResponse.readable():此方法使HttpResponse实例成为类似流的对象,值始终为False
HttpResponse.seekable():此方法使HttpResponse实例成为类似流的对象,值始终为False
HttpResponse.writable():此方法使HttpResponse实例成为类似流的对象,值始终为True
HttpResponse.writelines(lines):将一个包含行的列表写入响应对象中,不添加分行符
(4)HttpResponse子类
Django包含许多HttpResponse衍生类(子类),用来处理不同类型的HTTP响应,这些子类存在于django.http之中:
class HttpResponseRedirect:用来重定向,第一个参数必须是重定向到的路径,可以是完全限定的URL,或没有域的绝对路径,或者是相对路径;它将返回状态码302
class HttpResponsePermanentRedirect:永久重定向,返回301状态码
class HttpResponseNotModified:未修改页面,返回304状态码
class HttpResponseBadRequest:错误的请求,返回400状态码
class HttpResponseNotFound:页面不存在,返回404状态码
class HttpResponseForbidden:禁止访问,返回403状态码
class HttpResponseNotAllowed:禁止访问,返回405状态码
class HttpResponseGone:过期,返回410状态码
class HttpResponseServerError:服务器错误,返回500状态码
(5)JsonResponse类
classJsonResponse(data,encoder = DjangoJSONEncoder,safe = True,json_dumps_params = None,**kwargs)
JsonResponse是HttpResponse的一个子类,是Django提供的用于创建JSON编码类型响应的快捷类
它从父类继承大部分行为,并具有以下不同点:
它的默认Content-Type头部设置为application/json
它的第一个参数data,通常应该为一个字典数据类型,如果safe参数设置为False,则可以是任何可JSON序列化的对象
encoder默认为django.core.serializers.json.DjangoJSONEncoder,用于序列化数据
布尔类型参数safe默认为True,如果设置为False,可以传递任何对象进行序列化,否则只允许dict实例
典型的用法如下:
>>> from django.http import JsonResponse >>> response = JsonResponse({'foo': 'bar'}) >>> response.content b'{"foo": "bar"}'
如要序列非dict对象,必须设置safe参数为False,如果不传递safe=False,将抛出一个TypeError
>>> response = JsonResponse([1, 2, 3], safe=False)
如果你需要使用不同的JSON编码器类,可以传递encoder参数给构造函数:
>>> response = JsonResponse(data, encoder=MyJSONEncoder)
(6)StreamingHttpResponse类
StreamingHttpResponse类被用来从Django响应一个流式对象到浏览器。如果生成的响应太长或者是占用的内存较大,这么做可能更有效率。 例如,它对于生成大型的CSV文件非常有用。
StreamingHttpResponse不是HttpResponse的衍生类(子类),因为它实现了完全不同的应用程序接口。但是,除了几个明显不同的地方,两者几乎完全相同:
它将被赋予一个迭代器,产生字符串作为内容
除非通过迭代响应对象本身,否则无法访问其内容,只有在将响应返回给客户端时才会发生这种情况
它没有content属性,相反,它有一个streaming_content属性
你不能使用类文件对象tell()或write()方法
(7)FileResponse类
class FileResponse(open_file,as_attachment = False,filename='',**kwargs)
文件类型响应,通常用于给浏览器返回一个文件附件,FileResponse是StreamingHttpResponse的衍生类,为二进制文件专门做了优化
如果as_attachment=True,则要求浏览器将文件作为下载提供给用户
如果open_file没有名称或名称open_file不合适,请使用filename参数提供自定义文件名
FileResponse接受任何具有二进制内容的类文件对象,如下以二进制模式打开文件:
>>> from django.http import FileResponse >>> response = FileResponse(open('myfile.png', 'rb'))
上面的文件将自动关闭,因此不要使用上下文管理器打开它
FileResponse.set_headers方法,在2.1中添加的新功能,它在初始化期间自动调用和设置不同的报头(Content-Length,Content-Type和Content-Disposition),使用哪种报头取决于打开的文件。
-------------------------------------------------------------------------------------------------------------------