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')
方式二

 

posted @ 2018-11-24 17:22  Sakura_L  阅读(515)  评论(0编辑  收藏  举报