首页 > 编程语言 >CBV、APIView源码分析

CBV、APIView源码分析

时间:2023-08-31 15:01:01浏览次数:45  
标签:request self APIView --- 源码 CBV View view

一、CBV源码分析

1、功能需求

基于类的视图---> 使用类编写---> 在类中写跟请求方式(methon)同名的方法---> 路由配置 类名.as_view()

前端的请求过来,什么请求,就会执行跟请求方式同名的方法

2、执行流程

路由匹配成功---> 配置在路由上的第二个参:执行函数内存地址自动加(request)---> 执行view(request)---> 执行了self.dispatch --->BookView没有---> 找到了父类View---> dispatch--->
handler = getattr(self, 'get') 反射 ---> return handler(request, *args, **kwargs)

3、源码

# View.as_view的源码
@classonlymethod
def as_view(cls, **initkwargs):
    # 闭包函数
    def view(request, *args, **kwargs):
        self = cls(**initkwargs) # 类实例化得到对象:BookView的对象
        # 调用对象的绑定方法 dispath---》去BookView中找dispatch--》找不到去父类---》View中的dispatch
        return self.dispatch(request, *args, **kwargs) # 对象的方法
    return view
    
# 执行:BookView.as_view()(request)---》本质是执行 View中as_view内部的view方法,传入了reuqest----》在执行View的dispatch方法,传入了request

# 看 :View.dispatch---》源码
    def dispatch(self, request, *args, **kwargs):
        if request.method.lower() in self.http_method_names: # 判断请求方式是否在那个固定的列表中[get, post...]--->
            # 反射:通过字符串 动态的  操作对象的属性或方法
            # 假设是get请求---》去BookView中取出 get方法赋值给handler
            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed
        # 执行handler加括号,传入了request
        # 本质是执行 get(request)
        return handler(request, *args, **kwargs)

二、APIView源码分析

1、基于drf的APIView写接口

#1  使用drf,以后都写cbv---> 继承一个视图类---> 以后都继承drf提供 的APIView

#2  APIView 继承了djagno的View

#3  补充:这三个都是一个
from django.views import View
from django.views.generic import View
from django.views.generic.base import View


# 4 继承APIView写cbv---> 执行起来跟之前效果一样---> 内部发生了非常大的变化
    1 写视图类
    from rest_framework.views import APIView
    class PublishView(APIView):
        def get(self, request):                                                                                                 
            return JsonResponse({'code': 999})
    2 配置路由
    path('publish/', PublishView.as_view()),

2、执行流程

	路由匹配成功---》BookView.as_view()--->APIView的as_view配置在路由上的第二个参:执行函数内存地址(request)---》执行View的view(request)--》但是它去除了csrf认证---》dispatch---》APIView的dispatch---》
    1 包装了新的request---》视图类的方法中的request是新的
    2 执行三大认证
    3 处理了全局异常

3、源码分析

# 比之前继承django的View多了如下
	-0 去除了csrf认证
	-1 包装了新的request
        -2 执行了认证,频率,权限 这三大认证
        -3 全局异常处理:在视图类的方法中执行报错,会被异常捕获,做统一处理
    
    
# 执行流程分析
	-请求来了---》执行PublishView.as_view()(request)--->PublishView类没有as_view---》找父类---》APIView的as_view
    -APIView的as_view---》本质在禁用csrf认证
    @classmethod
    def as_view(cls, **initkwargs):
        # 调用父类的as_view得到返回值赋值给view---》django的View的as_view【看过】---》返回View的as_view的闭包函数 view
        view = super().as_view(**initkwargs)  # 现在这个view就是原来看的View的as_view的view
        # 去除了csrf认证----》局部禁用csrf---》在视图函数上加 装饰器csrf_exempt
        # 加了装饰器的本质:    被装饰的函数=装饰器(被装饰的函数)
        return csrf_exempt(view)
    
    
    -PublishView.as_view()(request)--》执行了禁用掉csrf的View的as_view的view---》self.dispath--->APIView的dispath
     def dispatch(self, request, *args, **kwargs):
        # 1 包装了新的request对象
        request = self.initialize_request(request, *args, **kwargs)
        # 把新的request,赋值给了 self.request
        # self 是 PublishView的对象 
        self.request = request
        try:
            # 2 执行了3大认证
            self.initial(request, *args, **kwargs)
            
            ######开始### 跟之前View的dispath是一样的---》根据请求方式执行类中同名方法
            ###执行视图类的方法
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed

            response = handler(request, *args, **kwargs)
            ######结束###
            
            
		# 执行三大认证和视图类的方法,如果出了异常,抛了错,会被捕获,统一处理
        except Exception as exc:
            response = self.handle_exception(exc)

        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response
    
    
    
# 装饰器的本质

@auth  # add=auth(add)-->以后调用add 实际上调用   auth(add)()
def add():
    pass

add=auth(add)


### 包装新的request
	# 1 request.data:前端传入的数据(post,put,编码格式)--->写到在请求体中的数据,都用
    # 2 老request中有 request.GET 新的使用request.query_params 充当
    # 3 其他的所有属性方法,用起来跟之前一样
    
    
### 三大认证
	    self.perform_authentication(request)
        self.check_permissions(request)
        self.check_throttles(request)
        
        
### 处理了全局异常,统一处理了

4、 总结:

视图类继承APIView后多了
-0 去除了csrf认证
-1 新的request
   -request.data
   -request.query_params
   -request.其他跟之前一样
   -request._request  是老的
-2 三大认证
-3 全局异常

  

标签:request,self,APIView,---,源码,CBV,View,view
From: https://www.cnblogs.com/dgp-zjz/p/17669513.html

相关文章

  • HashMap 源码分析
    HashMap简介HashMap主要用来存放键值对,它基于哈希表的Map接口实现,是常用的Java集合之一,是非线程安全的。HashMap可以存储null的key和value,但null作为键只能有一个,null作为值可以有多个JDK1.8之前HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主......
  • [内核源码] epoll 实现原理
    https://wenfh2020.com/2020/04/23/epoll-code/文章主要对tcp通信进行epoll源码走读。Linux源码:Linux5.7版本。epoll核心源码:eventpoll.h/eventpoll.c。搭建epoll内核调试环境视频:vscode+gdb远程调试linux(EPOLL)内核源码1.应用场景2.预备知识3.使......
  • flask之cbv源码分析,模板,请求与响应,session和源码分析,闪现,请求扩展
    目录1cbv分析1.1源码分析2模板2.1py2.2html3请求与响应4session及源码分析4.1session的使用4.2源码分析4.3session执行原理5闪现6请求扩展1cbv分析#基于类的视图,写法fromflaskimportFlask,requestfromflask.viewsimportView,MethodViewapp=Flask(__......
  • restful规范和django源码写接口
    一、restful规范1、restful规范是什么,如何来的?一种定义WebAPI接口的设计风格,尤其适用于前后端分离的应用模式中的规范RoyFielding的博士论文提出的2、以后写接口,大致都要遵循如下规范-1数据的安全保障-》url链接一般都采用https协议进行传输--》它比http安全......
  • ArrayList 源码分析
    ArrayList简介ArrayList的底层是数组队列,相当于动态数组。与Java中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用ensureCapacity操作来增加ArrayList实例的容量。这可以减少递增式再分配的数量。ArrayList继承于AbstractList,实现了List,RandomAcc......
  • 医学影像信息系统源码(PACS)
    影像信息系统(PACS)可接收和显示多种设备的不同影像,比如CT、DR、B超和彩超等,具有医学影像获取、存档、观片、处理、打印和多种管理功能。使资料保存更加完整,共享性更强。医生可以方便的对影像资料进行浏览、拷贝和光盘刻录,支持院内会诊和远程会诊,最终实现与与医院其他系统及设备无缝......
  • ArrayList源码阅读之EMPTY_ELEMENTDATA和DEFAULTCAPACITY_EMPTY_ELEMENTDATA区别
    /***Sharedemptyarrayinstanceusedforemptyinstances.*/privatestaticfinalObject[]EMPTY_ELEMENTDATA={};/***Sharedemptyarrayinstanceusedfordefaultsizedemptyinstances.We*distinguishthisfromEMPTY_ELEMENTDATAtoknowhowmuchtoi......
  • 直播带货源码,RecyclerView横向导航条目出现
    直播带货源码,RecyclerView横向导航条目出现/** *RecyclerView移动到当前位置, * *@parammanager  设置RecyclerView对应的manager *@parammRecyclerView 当前的RecyclerView *@paramn 要跳转的位置 */publicstaticvoidMoveToPosition(LinearLayoutManager......
  • 你是如何阅读jdk源码的?
    阅读别人的代码作为开发人员是一件经常要做的事情。一个是学习新的编程语言的时候通过阅读别人的代码是一个最好的学习方法,另外是积累编程经验。如果你有机会阅读一些操作系统的代码会帮助你理解一些基本的原理。还有就是在你作为一个质量保证人员或一个小领导的时候如果你要做白盒......
  • 个人相册管理系统-计算机毕业设计源码+LW文档
    随着社会的发展,人们生活水平的 提高,网络科技和云端技术的完善,越来越多的人喜欢通过拍照的方式把生活中美好的事物以及一瞬间记录下来,但是随着照片越来越多,传统的相册已经不能满足我们的基本需求,不方便携带,也不方便与他人分享。这个时候,网络个人相册就能解决这些问题,不光能保存大量......