django中的CBV
CBV介绍
我们在写一个django项目时,通常使用的都是FBV(function base views)
而CBV(class base views)也有它自己的应用场景,比如在写一个按照rest规范写接口时,CBV的适用性就比FBV更强
先来看看CBV在django中的写法,与FBV有什么不同的地方
url(r'^students/', views.StudentsView.as_view())
from django.views import View class StudentsView(View): def get(self,request,*args,**kwargs): return HttpResponse('GET') def post(self, request, *args, **kwargs): return HttpResponse('POST') def put(self, request, *args, **kwargs): return HttpResponse('PUT') def delete(self, request, *args, **kwargs): return HttpResponse('DELETE')
首先,在views中定义的类是要继承django中的View类的,而StudentsView中并未定义as_view()这个方法,所以它会去执行View中的as_view方法
而as_view方法的返回值就是一个函数,这个函数是在as_view中的内部定义的
那么在我们访问url的时候,django会去调用这个view函数,view函数又去调用了self.dispatch方法,并返回了这个方法的返回值
所以查看一下dispatch这个方法
它就是对这个请求的method做了一个反射的操作,找到这个请求类型对应的方法然后去执行它,lower()的作用就是把method中的GET/POST等大写的方法名转化成小写的函数名,这样我们只需要在类中定义好小写的函数名就可以完成调用了
原理:
url -> view方法 -> dispatch方法(反射执行其他:GET/POST/DELETE/PUT)
流程: class StudentsView(View): def dispatch(self, request, *args, **kwargs): print('before') ret = super(StudentsView,self).dispatch(request, *args, **kwargs) print('after') return ret def get(self,request,*args,**kwargs): return HttpResponse('GET') def post(self, request, *args, **kwargs): return HttpResponse('POST') def put(self, request, *args, **kwargs): return HttpResponse('PUT') def delete(self, request, *args, **kwargs): return HttpResponse('DELETE') 继承(多个类共用的功能,为了避免重复编写): from django.views import View class MyBaseView(object): def dispatch(self, request, *args, **kwargs): print('before') ret = super(MyBaseView,self).dispatch(request, *args, **kwargs) print('after') return ret class StudentsView(MyBaseView,View): # 继承时要先继承我们自己定义的类,这样才有效,如果先继承View那么就会先去执行原码中的dispatch方法了 def get(self,request,*args,**kwargs): print('get方法') return HttpResponse('GET') def post(self, request, *args, **kwargs): return HttpResponse('POST') def put(self, request, *args, **kwargs): return HttpResponse('PUT') def delete(self, request, *args, **kwargs): return HttpResponse('DELETE') class TeachersView(MyBaseView,View): def get(self,request,*args,**kwargs): return HttpResponse('GET') def post(self, request, *args, **kwargs): return HttpResponse('POST') def put(self, request, *args, **kwargs): return HttpResponse('PUT') def delete(self, request, *args, **kwargs): return HttpResponse('DELETE')
CBV中关于csrf一些需要注意的点
首先要知道csrf是如何实现的
django中的csrf是通过中间件中的process_view()方法来实现的
实现的过程分为两步:
第一步:检查视图是否被@csrf_exempt装饰器装饰
第二步:去请求体或cookie中获取token对应的值,并用算法与服务器发送给浏览器上的token值进行对比校验
情况一: MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', # 全站使用csrf认证 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] from django.views.decorators.csrf import csrf_exempt @csrf_exempt # 该函数无需认证 def users(request): user_list = ['alex','oldboy'] return HttpResponse(json.dumps((user_list)))
情况二: MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', # 全站不使用csrf认证 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] from django.views.decorators.csrf import csrf_exempt @csrf_protect # 该函数需认证 def users(request): user_list = ['alex','oldboy'] return HttpResponse(json.dumps((user_list)))
CBV小知识
csrf时需要使用
- @method_decorator(csrf_exempt)
- 在dispatch方法中(单独方法无效)
在cbv中使用csrf的方式也有两种
方式一: from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decorator class StudentsView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(StudentsView,self).dispatch(request, *args, **kwargs) def get(self,request,*args,**kwargs): print('get方法') return HttpResponse('GET') def post(self, request, *args, **kwargs): return HttpResponse('POST') def put(self, request, *args, **kwargs): return HttpResponse('PUT') def delete(self, request, *args, **kwargs): return HttpResponse('DELETE')
方式二: from django.views.decorators.csrf import csrf_exempt,csrf_protect from django.utils.decorators import method_decorator @method_decorator(csrf_exempt,name='dispatch') class StudentsView(View): def get(self,request,*args,**kwargs): print('get方法') return HttpResponse('GET') def post(self, request, *args, **kwargs): return HttpResponse('POST') def put(self, request, *args, **kwargs): return HttpResponse('PUT') def delete(self, request, *args, **kwargs): return HttpResponse('DELETE')