CBV源码分析

 创建类视图

view.py

url.py

一定要加括号!然后按住ctrl点进去就可以看as_view的源码

这是一个闭包函数,view函数里的cls是对外部作用域的cls的引用,不能说是装饰器,装饰器是闭包函数的一个应用

这里的self是view这个类的对象,我们在类视图继承了view这个类,就是我们Test这个类的对象,这里返回了一个dispatch方法,但是我们并没有定义这个方法,所以就去Test的父类View里面去找

    def dispatch(self, request, *args, **kwargs):
        # Try to dispatch to the right method; if a method doesn't exist,
        # defer to the error handler. Also defer to the error handler if the
        # request method isn't on the approved list.
        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)

这里面的放了所有http的请求方式

并且可以重写http_method_names

如果发送过来的请求方式不在这里面就会执行

如果在这里面通过反射getattr去这self这个对象里也就是Test这个类的对象通过传过来的名字比如get去取东西,所以类里面的get必须带request

因为内部返回了*args,**kwargs,为了规范在类视图函数里也要加上

 这里面的*args,**kwargs也就是urls路由里面的有名分组或者无名分组分出来的参数

 如果这里加了一个

并不是同一个内存地址。因为不是执行一个self对象

也可以重写dispatch方法

因为内部有返回值,这里也需要返回,如果不想在中间件中写东西,可以这里面写,如果这样写,来了请求一定会先过了中间件然后走这里面,

执行流程:

-路由如果这么配置:url(r'^test/', views.Test.as_view()),执行后面 views.Test.as_view()再加括号
请求通过中间件后进入路由--->根据路由匹配,一旦成功,会执行后面函数(request)---》本质就是执行了as_view内部的view函数----》内部又调用了self.dispatch---->根据请求方式,执行不同的方法(必然get请求,就会执行咱么写的视图类的get方法)

原文地址:https://www.cnblogs.com/zhengyuli/p/11115908.html