Django【进阶】FBV 和 CBV

django中请求处理方式有2种:FBV 和 CBV

 

一、FBV

FBV(function base views) 就是在视图里使用函数处理请求。

看代码:

urls.py

1
2
3
4
5
6
7
8
fromdjango.conf.urlsimporturl, include
# from django.contrib import admin
frommytestimportviews
 
urlpatterns=[
# url(r‘^admin/‘, admin.site.urls),
url(r‘^index/‘, views.index),
]

views.py

1
2
3
4
5
6
7
8
9
fromdjango.shortcutsimportrender
 
 
defindex(req):
ifreq.method==‘POST‘:
print(‘methodis:‘+req.method)
elifreq.method==‘GET‘:
print(‘methodis:‘+req.method)
returnrender(req, ‘index.html‘)

注意此处定义的是函数【def index(req):】

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<form action="" method="post">
<inputtype="text"name="A"/>
<inputtype="submit"name="b"value="提交"/>
</form>
</body>
</html>

上面就是FBV的使用。

二、CBV

1、CBV(class base views) 就是在视图里使用类处理请求。

分别处理get和post请求

 

 

get和post方法是如何被调用的?????

  实际上父类View中有一个dispatch方法,作用就是通过反射来调用子类的get和post方法。

请求先走dispatch,res就是get方法或者post方法执行只有的结果

所以这个请求的过程是:请求--->dispatch--->get/post

我们现在把dispatch写到子类中,继承父类的dispatch方法。dispatch写到子类或者单独写一个类,目的是根据需求加功能。

 

2、我现在想实现验证登录的功能用CBV实现登录验证不如用中间件,所以我们一般用中间件来实现验证功能

下面的函数是实现登录的

   def dispatch(self, request, *args, **kwargs):
        return super(LoginView,self).dispatch(request, *args, **kwargs)

    def get(self,request):
        print('login')
        return render(request,'login.html')


    def post(self,request):
        # request.GET
        # request.POST # 请求头中的:content-type
        # 注意:request.POST中的数据是request.body中转换过来的,可能为空,因为可能转换会不成功
        # request.body    但凡以post提交数据,request.body中一定有值
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'alex' and pwd == "alex3714":
            
            # 生成随机字符串
            # 写浏览器cookie: session_id: 随机字符串
            # 写到服务端session:
            # {
            #     "随机字符串": {'user_info':'alex}
            # }
            request.session['user_info'] = "alex"    # 这个代码有上面注释的几个操作
            
            return redirect('/index.html')
        return render(request, 'login.html')

 

 

 把dispatch拿出来单独写一个类,这个类提供验证登录的功能,让其他类来继承,如下:
class AuthView(object):
    def dispatch(self, request, *args, **kwargs):
        if not request.session.get('user_info'):
            return redirect('/login.html')
        res = super(AuthView,self).dispatch(request, *args, **kwargs)
        return res

class IndexView(AuthView,View):
    def get(self,request,*args,**kwargs):
        return render(request,'index.html')

    def post(self,request,*args,**kwargs):
        return HttpResponse('999')

    
class OrderView(AuthView,View):
    def get(self,request,*args,**kwargs):
        return render(request,'index.html')

    def post(self,request,*args,**kwargs):
        return HttpResponse('999')

  

 

 

 
3、对于CBV加装饰器的方法

 

如果加装饰器,需要导入method_decorator

 

加装饰的格式@method_decorator(test),test是装饰器函数

def test(func):
    def inner(*args,**kwargs):
        return func(*args,**kwargs)
    return inner

  

 可以加在类上,但是加到类上需要指定使用的方法名
@method_decorator(test,name='get')
class LoginView(View):
 

可以加到dispatch方法,也可以加到get或post方法,不需要传name="方法名"

@method_decorator(test)
def dispath(self,request,*args,**kwargs):

  

 

4、特殊装饰器:CSRF Token只能加到dispatch(django的bug)

CBV的csrf装饰器需要导入

from django.views.decorators.csrf import csrf_exempt,csrf_protect
 
csrf_exempt是全局需要,唯独这个不需要
csrf_protect是全局不需要,唯独这个需要
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
	return super(LoginView,self).dispatch(request, *args, **kwargs)

  

 

posted on 2017-09-20 23:02  lucaq  阅读(267)  评论(0编辑  收藏  举报

导航