Django CBV源码分析
django视图层中FBV与CBV
简介
视图函数既可以是函数也可以是类
FBV(function base views)
就是在视图里使用函数处理请求,在之前django的学习中,一直使用的方式
CBV(class base views)
CBV基本使用
就是在视图里使用类处理请求
Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:
- 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
- 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
CBV源码分析
当浏览器客户端向服务端发送请求时,会先通过路由匹配到对应的视图函数并加括号调用。
在路由层中书写的路由与视图函数的对应关系,路由对应的必须是一个函数地址,因此CBV本质还是FBV,由此可以推断views.MyView.as_view()
中的as_view应该是一个类方法,并且该方法加括号调用后返回的结果是一个函数的内存地址。
as_view方式是自定义视图类调用的,但是自定义视图类MyView
中并没有该方法,按照面向对象的属性查找顺序,as_view方法是在MyView
的父类View
中定义的
- 进入as_view方法
当匹配到视图类的时候,会加()
运行views.MyView.as_view()
views.MyView.as_view()
运行的结果是返回as_view方法内部的view
函数的内存地址
在self.setup
方法中,会将当次请求的request对象作为属性添加给当前对象
路由对应的是view方法的内存地址,因此当匹配到路由时会加()
运行view
方法
根据上图可以发现,运行view
方法会返回self.dispatch()
方法的运行结果
在dispatch方法中会获取对象(MyView
的对象)的请求方式然后小写,判断是否在self.http_method_names
中,如果在就通过反射将对象的请求方式小写赋值给handler,,最后返回handler加()
调用。
CBV视图层中,dispatch方法可以说是前端向后端发送请求的调度员,可以根据不同的请求的方式执行视图类中对应的方法
例如:前端向后端根据url发送了get请求,后端会根据路由与视图的对应关系执行对应的视图类,就会运行as_view方法,通过运行as_view方式,返回了view方法的内存地址,加()调用,
view()
的运行会返回dispatch方法的运行,在dispatch方法中获取到前端发送请求的方式,然后小写,即为get,最后返回get加()
调用