zoukankan      html  css  js  c++  java
  • 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')
    方式二
  • 相关阅读:
    html和css简介;
    包装函数,面向切面的函数实现;
    RegExp
    javascript基础语法&5
    用Pyinstaller把Python3.7程序打包成可执行文件exe
    Idea下安装Lombok插件
    Moco框架jar下载地址
    安装时后的idea,项目不能运行,pom.xml文件不能下载到本地仓库,maven配置是正确的
    如何使用Git命令将项目从github或者服务器上克隆下来
    github怎么创建一个项目,怎么添加一个ssh-key的客户
  • 原文地址:https://www.cnblogs.com/louyifei0824/p/10012775.html
Copyright © 2011-2022 走看看