• DRF学习之CBV源码分析流程


    CBV源码分析流程

    urls.py

    from django.contrib import admin
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        ...
        path('test/',views.Test.as_view()), # path里面放了一个view的内存地址
    ]
    

    看下 as_views方法

    @classonlymethod 
    def as_view(cls, **initkwargs): #类方法,类调用自动将类作为参数传入,cls=Test
        ...
        # 闭包函数
        def view(request, *args, **kwargs): # 内层函数
            self = cls(**initkwargs) # 实例化一个对象
            if hasattr(self, 'get') and not hasattr(self, 'head'):
                self.head = self.get # 判断对象有没有的get方法
            self.request = request
            self.args = args
            self.kwargs = kwargs
    
            return self.dispatch(request, *args, **kwargs)
    
        # 一切皆对象,给对象赋值属性
        view.view_class = cls # 将类名赋值给view的view_class属性
        view.view_initkwargs = initkwargs 
    
        return view # 返回内层函数的内存地址
    
    # 流程
    在路由匹配阶段:views.Test.as_view()
    (1)Test类调用类方法as_view:自动将Test作为参数传入
    (2)as_view()是一个嵌套函数,它返回了内层函数的内存地址
    (3)view()闭包函数,引用外部的cls,返回的是self.dispatch(request,*args,**kwargs)
    

     再看下self.dispatch()

    self是一个Book对象,调用方法的查找顺序,先找自己的,没有去父类中找,再没有去父类的父类中找
    
    http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    
    def dispatch(self, request, *args, **kwargs):
       # request是当次请求的request self是Book类的实例化对象
       if request.method.lower() in self.http_method_names: #判断request,method的小写是否在http_method_names中
           handler = getattr(self, request.method.lower(), self.http_method_not_allowed) # 反射 hander是Book类get方法的内存地址
       else:
           handler = self.http_method_not_allowed
       return handler(request, *args, **kwargs) # 执行get(request,*args,**kwargs)
    

    原生的request对象

    http请求经过WSGI服务器会被拆分成一个env大字典,env大字典会包含http请求的所有数据。django框架会将env大字典中的数据封装给原生的request对象。而DRF框架中的request对象是对原生request的二次封装

    扩展点:

    # python中一切皆对象
    class Beast(object):
        def __init__(self, name):
            self.name = name
    
        def hello(self):
            print(f'hello,{self.name}')
    
    
    Beast.method = 'get'
    
    print(Beast.method) # get
    
  • 相关阅读:
    【python】变量定义及全局局部变量
    【python】重要的内置函数
    【python】迭代器iterator
    Java序列化与反序列化
    java中的IO操作总结
    Java中List Set Map 是否有序等总结
    java.lang.Class.getDeclaredMethod()方法详解
    一个servlet处理多个请求(使用Method的反射机制)
    java类的访问权限
    java中的基本数据类型存放位置
  • 原文地址:https://www.cnblogs.com/surpass123/p/13258125.html
Copyright © 2020-2023  润新知