Django 视图层

视图

一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求而且返回Web响应。响应能够是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西均可以。不管视图自己包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你的Python目录下面。除此以外没有更多的要求了。为了将代码放在某处,约定是将视图放置在项目或应用程序目录中的名为views.py的文件中。html

1、HttpRequest对象

django将请求报文中的请求行、首部信息、内容主体封装成 HttpRequest 类中的属性。python

"""
1、属性
1. HttpRequest.scheme
字符串类型,表示请求的协议种类,'http'或'https'。
 
2. HttpRequest.body
一个字符串,表明请求报文的主体。在处理非 HTTP 形式的报文时很是有用,例如:二进制图像、XML等。若是要处理常规的表单数据,应该使用HttpRequest.POST。
还可使用相似读写文件的方式从HttpRequest中读取数据,参见HttpRequest.read()。
 
3. HttpRequest.path
字符串类型,表示当前请求页面的完整路径,可是不包括协议名和域名。例如:"/music/bands/the_beatles/"。这个属性,常被用于咱们进行某项操做时,若是不经过,返回用户先前浏览的页面。很是有用!
 
4. HttpRequest.path_info
在某些Web服务器配置下,主机名后的URL部分被分红脚本前缀部分和路径信息部分。path_info 属性将始终包含路径信息部分,不论使用的Web服务器是什么。使用它代替path可让代码在测试和开发环境中更容易地切换。
 
例如,若是应用的WSGIScriptAlias设置为/minfo,那么HttpRequest.path等于/music/bands/the_beatles/ ,而HttpRequest.path_info为/minfo/music/bands/the_beatles/。
 
5. HttpRequest.method
字符串类型,表示请求使用的HTTP方法。默认为大写。 像这样:
 
if request.method == 'GET':
    do_something()
elif request.method == 'POST':
    do_something_else()
经过这个属性来判断请求的方法,而后根据请求的方法不一样,在视图中执行不一样的代码。
 
6. HttpRequest.encoding
一个字符串,表示提交的数据的编码方式(若是为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 'utf-8')。
这个属性是可写的,你能够修改它来修改访问表单数据使用的编码。
接下来对属性的任何访问(例如从 GET 或 POST 中读取数据)将使用新的 encoding 值。
若是你知道表单数据的编码不是 DEFAULT_CHARSET ,则使用它。
 
7. HttpRequest.content_type
Django1.10中新增。表示从CONTENT_TYPE头解析的请求的MIME类型。
 
8. HttpRequest.content_params
Django 1.10中新增。包含在CONTENT_TYPE标题中的键/值参数字典。
 
9 HttpRequest.GET
一个相似于字典的对象,包含GET请求中的全部参数。 详情参考QueryDict文档。
 
注意:键值对的值是多个的时候,好比checkbox类型的input标签,select标签,须要用:
request.POST.getlist("hobby")
 
10. HttpRequest.POST
一个包含全部POST请求的参数,以及包含表单数据的字典。 详情请参考QueryDict文档。 若是须要访问请求中的原始或非表单数据,可使用HttpRequest.body属性。
 
注意:请使用if request.method == "POST"来判断一个请求是否POST类型,而不要使用if request.POST。
POST中不包含上传文件的数据。文件信息将包含在 FILES 属性中。
 
11. HttpRequest.COOKIES
包含全部Cookie信息的字典。 键和值都为字符串。能够相似字典类型的方式,在cookie中读写数据,可是注意cookie是不安全的,所以,不要写敏感重要的信息。
 
12. HttpRequest.FILES
一个相似于字典的对象,包含全部的上传文件信息。
FILES 中的每一个键为<input type="file" name="" /> 中的name,值则为对应的数据。
注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的状况下才会
包含数据。不然,FILES 将为一个空的相似于字典的对象。
 
13. 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键。
 
13. HttpRequest.resolver_match
表明一个已解析的URL的ResolverMatch实例。
 
 
 
2、可自定义的属性
Django不会自动设置下面这些属性,而是由你本身在应用程序中设置并使用它们。
 
1. HttpRequest.current_app
表示当前app的名字。url模板标签将使用其值做为reverse()方法的current_app参数。
 
2. HttpRequest.urlconf
设置当前请求的根URLconf,用于指定不一样的url路由进入口,这将覆盖settings中的ROOT_URLCONF设置。
将它的值修改成None,能够恢复使用ROOT_URLCONF设置。
 
 
 
 
3、由中间件设置的属性
Django的contrib应用中包含的一些中间件会在请求上设置属性。
 
1. HttpRequest.session
一个既可读又可写的相似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。
SessionMiddleware中间件:一个可读写的,相似字典的对象,表示当前会话。咱们要保存用户状态,回话过程等等,靠的就是这个中间件和这个属性。
 
2. HttpRequest.site
CurrentSiteMiddleware中间件:get_current_site()方法返回的Site或RequestSite的实例,表明当前站点是哪一个。
 
Django是支持多站点的,若是你同时上线了几个站点,就须要为每一个站点设置一个站点id。
 
3. HttpRequest.user(用户认证组件下使用)
AuthenticationMiddleware中间件:表示当前登陆的用户的AUTH_USER_MODEL的实例,这个模型是Django内置的Auth模块下的User模型。若是用户当前未登陆,则user将被设置为AnonymousUser的实例。
可使用is_authenticated方法判断当前用户是否合法用户,以下所示:
 
 
  一个 AUTH_USER_MODEL 类型的对象,表示当前登陆的用户。
 
  若是用户当前没有登陆,user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你能够经过 is_authenticated() 区分它们。
 
    例如:
 
    if request.user.is_authenticated():
        # Do something for logged-in users.
    else:
        # Do something for anonymous users.
 
 
       user 只有当Django 启用 AuthenticationMiddleware 中间件时才可用。
 
     -------------------------------------------------------------------------------------
 
    匿名用户
    class models.AnonymousUser
 
    django.contrib.auth.models.AnonymousUser 类实现了django.contrib.auth.models.User 接口,但具备下面几个不一样点:
 
    id 永远为None。
    username 永远为空字符串。
    get_username() 永远返回空字符串。
    is_staff 和 is_superuser 永远为False。
    is_active 永远为 False。
    groups 和 user_permissions 永远为空。
    is_anonymous() 返回True 而不是False。
    is_authenticated() 返回False 而不是True。
    set_password()、check_password()、save() 和delete() 引起 NotImplementedError。
    New in Django 1.8:
    新增 AnonymousUser.get_username() 以更好地模拟 django.contrib.auth.models.User。
 
"""
request属性
"""
1.HttpRequest.get_full_path()
 
  返回 path,若是能够将加上查询字符串。
 
  例如:"/music/bands/the_beatles/?print=true"
 
 
2.HttpRequest.is_ajax()
 
  若是请求是经过XMLHttpRequest 发起的,则返回True,方法是检查 HTTP_X_REQUESTED_WITH 相应的首部是不是字符串'XMLHttpRequest'。
 
  大部分现代的 JavaScript 库都会发送这个头部。若是你编写本身的 XMLHttpRequest 调用(在浏览器端),你必须手工设置这个值来让 is_ajax() 能够工做。
 
  若是一个响应须要根据请求是不是经过AJAX 发起的,而且你正在使用某种形式的缓存例如Django 的 cache middleware,
   你应该使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 装饰你的视图以让响应可以正确地缓存。
"""
 
"""
1. HttpRequest.get_host()[source]
根据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()
                     
2. HttpRequest.get_port()[source]
使用META中HTTP_X_FORWARDED_PORT和SERVER_PORT的信息返回请求的始发端口。
 
3. HttpRequest.get_full_path()[source]
返回包含完整参数列表的path。例如:/music/bands/the_beatles/?print=true
 
4. HttpRequest.build_absolute_uri(location)[source]

返回location的绝对URI形式。 若是location没有提供,则使用request.get_full_path()的值。
 
例如:"https://example.com/music/bands/the_beatles/?print=true"
 
注:不鼓励在同一站点混合部署HTTP和HTTPS,若是须要将用户重定向到HTTPS,最好使用Web服务器将全部HTTP流量重定向到HTTPS。
 
5. HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)[source]
从已签名的Cookie中获取值,若是签名不合法则返回django.core.signing.BadSignature。
可选参数salt用来为密码加盐,提升安全系数。 max_age参数用于检查Cookie对应的时间戳是否超时。
 
6. HttpRequest.is_secure()[source]
若是使用的是Https,则返回True,表示链接是安全的。
 
7. HttpRequest.is_ajax()[source]
若是请求是经过XMLHttpRequest生成的,则返回True。
这个方法的做用就是判断,当前请求是否经过ajax机制发送过来的。
 
8. HttpRequest.read(size=None)[source]
9. HttpRequest.readline()[source]
10. HttpRequest.readlines()[source]
11. HttpRequest.xreadlines()[source]
12. HttpRequest.iter()
上面的几个方法都是从HttpRequest实例读取文件数据的方法。
 
能够将HttpRequest实例直接传递到XML解析器,例如ElementTree:
 
import xml.etree.ElementTree as ET
for element in ET.iterparse(request):
    process(element)
 
"""
request经常使用方法

2、HttpResponse对象

响应对象主要有三种形式:web

  • HttpResponse():HttpResponse()括号内直接跟一个具体的字符串做为响应体,比较直接很简单,因此这里主要介绍后面两种形式。
  • render():render方法就是将一个模板页面中的模板语法进行渲染,最终渲染成一个html页面做为响应体。
  • redirect():重定向一个URL
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"""
render(request, template_name[, context])
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。
参数:
  request: 用于生成响应的请求对象。
  template_name:要使用的模板的完整名称,可选的参数
  context:添加到模板上下文的一个字典。默认是一个空字典。若是字典中的某个值是可调用的,视图将在渲染模板以前调用它。
  render方法就是将一个模板页面中的模板语法进行渲染,最终渲染成一个html页面做为响应体。
"""
return render(request, "index.html" ,{ "timer" :ctime}) #  index.html 模板文件
# return render(request, "index.html", locals())  #
 
# HttpResponse
return HttpResponse(reverse( "app01:index" ))
return HttpResponse( "<h1>OK</h1>" )
 
#redirect
return redirect( "/index/" )
return redirect( 'http://baidu.com/' )
"""
1、使用方法
1. 传递一个字符串
return HttpResponse("<h1>OK</h1>")

2. 传递可迭代对象
HttpResponse会当即处理这个迭代器,并把它的内容存成字符串,最后废弃这个迭代器。好比文件在读取后,会马上调用close()方法,关闭文件。

3. 设置头部字段
能够把HttpResponse对象看成一个字典同样,在其中增长和删除头部字段。
>>> response = HttpResponse()
>>> response['Age'] = 120
>>> del response['Age']
注意!与字典不一样的是,若是要删除的头部字段若是不存在,del不会抛出KeyError异常。
HTTP的头部字段中不能包含换行。因此若是咱们提供的头部字段值包含换行符(CR或者LF),将会抛出BadHeaderError异常。

4. 告诉浏览器将响应视为文件附件
让浏览器以文件附件的形式处理响应, 须要声明content_type类型和设置Content-Disposition头信息。 例如,给浏览器返回一个微软电子表格:
>>> response = HttpResponse(my_data, content_type='application/vnd.ms-excel')
>>> response['Content-Disposition'] = 'attachment; filename="foo.xls"'

2、属性
1. HttpResponse.content
响应的内容。bytes类型。

2. HttpResponse.charset
编码的字符集。 若是没指定,将会从content_type中解析出来。

3. HttpResponse.status_code
响应的状态码,好比200。

4. HttpResponse.reason_phrase
响应的HTTP缘由短语。 使用标准缘由短语。

除非明确设置,不然reason_phrase由status_code的值决定。

5. HttpResponse.streaming
这个属性的值老是False。因为这个属性的存在,使得中间件可以区别对待流式响应和常规响应。

6. HttpResponse.closed
若是响应已关闭,那么这个属性的值为True。

3、 方法
1. HttpResponse.init(content='', content_type=None, status=200, reason=None, charset=None)[source]
响应的实例化方法。使用content参数和content-type实例化一个HttpResponse对象。

content应该是一个迭代器或者字符串。若是是迭代器,这个迭代期返回的应是一串字符串,而且这些字符串链接起来造成response的内容。 若是不是迭代器或者字符串,那么在其被接收的时候将转换成字符串。

content_type是可选地,用于填充HTTP的Content-Type头部。若是未指定,默认状况下由DEFAULT_CONTENT_TYPE和DEFAULT_CHARSET设置组成:text/html; charset=utf-8。

status是响应的状态码。reason是HTTP响应短语。charset是编码方式。

2. HttpResponse.has_header(header)
检查头部中是否有给定的名称(不区分大小写),返回True或 False。

3. HttpResponse.setdefault(header, value)
设置一个头部,除非该头部已经设置过了。

4. 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。例如domain=".lawrence.com"将设置一个www.lawrence.com、blogs.lawrence.com和calendars.lawrence.com均可读的Cookie。 不然,Cookie将只能被设置它的域读取。

若是你想阻止客服端的JavaScript访问Cookie,能够设置httponly=True。

5. HttpResponse.set_signed_cookie(key, value, salt='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=True)
与set_cookie()相似,可是在设置以前将对cookie进行加密签名。一般与HttpRequest.get_signed_cookie()一块儿使用。

6. HttpResponse.delete_cookie(key, path='/', domain=None)
删除Cookie中指定的key。

因为Cookie的工做方式,path和domain应该与set_cookie()中使用的值相同,不然Cookie不会删掉。

7. HttpResponse.write(content)[source]
将HttpResponse实例看做相似文件的对象,往里面添加内容。

8. HttpResponse.flush()
清空HttpResponse实例的内容。

9. HttpResponse.tell()[source]
将HttpResponse实例看做相似文件的对象,移动位置指针。

10. HttpResponse.getvalue()[source]
返回HttpResponse.content的值。 此方法将HttpResponse实例看做是一个相似流的对象。

11. HttpResponse.readable()
Django1.10中的新功能,值始终为False。

12. HttpResponse.seekable()
Django1.10中的新功能,值始终为False。

13. HttpResponse.writable()[source]
Django1.10中的新功能,值始终为True。

14. HttpResponse.writelines(lines)[source]
将一个包含行的列表写入响应对象中。 不添加分行符。

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

class HttpResponseRedirect[source]:重定向,返回302状态码。已经被redirect()替代。
class HttpResponsePermanentRedirect[source]:永久重定向,返回301状态码。
class HttpResponseNotModified[source]:未修改页面,返回304状态码。
class HttpResponseBadRequest[source]:错误的请求,返回400状态码。
class HttpResponseNotFound[source]:页面不存在,返回404状态码。
class HttpResponseForbidden[source]:禁止访问,返回403状态码。
class HttpResponseNotAllowed[source]:禁止访问,返回405状态码。
class HttpResponseGone[source]:过时,返回405状态码。
class HttpResponseServerError[source]:服务器错误,返回500状态码。


5、JsonResponse类
class JsonResponse(data,encoder = DjangoJSONEncoder,safe = True,json_dumps_params = None ,** kwargs)[source]

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:

>>> response = JsonResponse([1, 2, 3], safe=False)
若是不传递safe=False,将抛出一个TypeError。
若是你须要使用不一样的JSON 编码器类,能够传递encoder参数给构造函数:
>>> response = JsonResponse(data, encoder=MyJSONEncoder)

6、StreamingHttpResponse类
StreamingHttpResponse类被用来从Django响应一个流式对象到浏览器。若是生成的响应太长或者是占用的内存较大,这么作可能更有效率。 例如,它对于生成大型的CSV文件很是有用。

StreamingHttpResponse不是HttpResponse的衍生类(子类),由于它实现了彻底不一样的应用程序接口。可是,除了几个明显不一样的地方,二者几乎彻底相同。

7、FileResponse
文件类型响应。一般用于给浏览器返回一个文件附件。

FileResponse是StreamingHttpResponse的衍生类,为二进制文件专门作了优化。

FileResponse须要经过二进制模式打开文件,以下:

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

"""
HttpResponse对象

3、自定义错误页面

当Django找不到与请求匹配的URL时,或者当抛出一个异常时,将调用一个错误处理视图。错误视图包括400、40三、404和500,分别表示请求错误、拒绝服务、页面不存在和服务器错误。它们分别位于ajax

  • handler400 —— django.conf.urls.handler400。
  • handler403 —— django.conf.urls.handler403。
  • handler404 —— django.conf.urls.handler404。
  • handler500 —— django.conf.urls.handler500。

这些值能够在根URLconf中设置。在其它app中的二级URLconf中设置这些变量无效。django

Django有内置的HTML模版,用于返回错误页面给用户,可是这些403,404页面实在丑陋,一般咱们都自定义错误页面。json

首先,在根URLconf中额外增长下面的条目:跨域

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from django.conf.urls import url
from django.conf.urls import include
from django.contrib import admin
from . import views
 
urlpatterns = [
     url(r '^admin/' , admin.site.urls),
     url(r '^backend/' ,include( 'backend.urls' )),
     url(r '^' , include( 'web.urls' )),
]
 
# 增长的条目
handler400 = views.bad_request
handler403 = views.permission_denied
handler404 = views.page_not_found
handler500 = views.page_error

而后在,views.py文件中增长四个处理视图:浏览器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.shortcuts import render
def page_not_found(request):
     return render(request, '404.html' )
 
 
def page_error(request):
     return render(request, '500.html' )
 
 
def permission_denied(request):
     return render(request, '403.html' )
 
 
def bad_request(request):
     return render(request, '400.html' )
相关文章
相关标签/搜索