• django_CBV理解


    路由如下,同时视图文件下存在class AuthView继承于 django.views.View:

    urlpatterns = [
        path('api/v1/auth/', views.AuthView.as_view()),
    ]


    然后查看对应Views.py文件中,发现并没有定义as_view()这个方法,所以一定是父类View中的方法
    查看as_view源码,先只贴如下部分

    class View:
        http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    
        def __init__(self, **kwargs):
            for key, value in kwargs.items():
                setattr(self, key, value)
    
        @classonlymethod
        def as_view(cls, **initkwargs):
            """Main entry point for a request-response process."""
            #一般我们没有对as_view()传递任何参数,相当于initkwargs={},所以这个循环就直接跳过了
            for key in initkwargs:
                #如果as_view()传递了参数过来,但是字典的key是属于http_method_names中的一个,比如get=''、post=''......报如下错误
                if key in cls.http_method_names:
                    raise TypeError("You tried to pass in the %s method name as a "
                                    "keyword argument to %s(). Don't do that."
                                    % (key, cls.__name__))
                #如果传递过来的参数,比如传递views.AuthView.as_view(name='kobe'),但是在AuthView这个类中没有name这个属性,就会报错如下
                if not hasattr(cls, key):
                    raise TypeError("%s() received an invalid keyword %r. as_view "
                                    "only accepts arguments that are already "
                                    "attributes of the class." % (cls.__name__, key))
    
            def view(request, *args, **kwargs):
                #这里的self=传递进来的类的实例化  即 自定义的这个AuthView类的实例化
                self = cls(**initkwargs)
                if hasattr(self, 'get') and not hasattr(self, 'head'):
                    self.head = self.get
                self.setup(request, *args, **kwargs)
                if not hasattr(self, 'request'):
                    raise AttributeError(
                        "%s instance has no 'request' attribute. Did you override "
                        "setup() and forget to call super()?" % cls.__name__
                    )
                #然后经过这些操作之后,返回dispatch方法,如果在views.py中的AuthView中我们自己重写了dispatch方法,就执行重写的,否则执行父类也就是现在这个类中的该方法
                return self.dispatch(request, *args, **kwargs)
            #给View函数添加属性,这在django中很常见,就好比声明一个函数fun1,里面不带任何东西,然后声明一个类A,可以直接把A绑定到函数里面去fun1.fun1_class=A
            #这里绑定的是cls,就是这个类AuthView
            view.view_class = cls
            #如果as_view()有传递参数过来,同时绑定参数
            view.view_initkwargs = initkwargs
    
            # take name and docstring from class
            #update_wrapper(A,B)把B的相关属性赋值给A,当想要装饰某一个函数,但是又想要保持函数本身的属性的时候用到update_wrapper
            update_wrapper(view, cls, updated=())
    
            # and possible attributes set by decorators
            # like csrf_exempt from dispatch
            update_wrapper(view, cls.dispatch, assigned=())
            #经过一系列加工之后,返回view
            return view
            
        def dispatch(self, request, *args, **kwargs):
            # 这里的self,指的是自定义的CBV类实例化得到的对象(AuthView)
            #在dispatch方法中,把request.method转换为小写再判断是否在定义的http_method_names中,如果request.method存在于http_method_names中,则使用getattr反射的方式来得到handler
            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
            return handler(request, *args, **kwargs)

    执行步骤:

    1.类名去调用as_view方法

    2.as_view返回一个view方法名

    3.urls执行view方法

    4.执行到view方法self = cls(**initkwargs)#实例化一个对象cls对应的就是 自己写的那个视图类

    5. 继续往下执行return self.dispatch(request, *args, **kwargs)#这时self是自己写的视图类的实例化对象 去该类中去寻找dispatch方法

    6.LoginView视图类没有找到去对应的父类View去寻找

    dispatch方法

    7.找到http_method_names对应属性里面有各类方法

    8.请求的方法名在这个属性中继续往下执行反射

    9.利用反射去寻找对应的方法

    #注意

    getattr 第二个参数找不到就执行第三个参数 执行第三个方法直接报错返回 日志打印405

  • 相关阅读:
    C# 互操作性入门系列(三):平台调用中的数据封送处理
    C# 互操作性入门系列(二):使用平台调用调用Win32 函数
    C# 互操作性入门系列(一):C#中互操作性介绍
    远程桌面打开 提示无法打开连接文件 default.rdp
    C# for循环 创建model 在循环里和循环外引发的问题
    C# 使用ListView.CheckedItems慢的问题
    获取数据库信息
    获取文件路径
    String数据转Matrix矩阵
    文件IO(存取.txt文件)
  • 原文地址:https://www.cnblogs.com/alantammm/p/13937126.html
Copyright © 2020-2023  润新知