Django 实现视图的方法有两种, 一种是 FBV(function base view)即基于函数的视图, 还一种高级的就是 CBV(class base view), 通过阅读源码你会发现它本质上还是基于 FBV 的. FBV 的优点是用法和写法都比较简单适合刚开始学的同学使用, 缺点就是不能用的面向对象的几大特性只用函数进行封装代码多的时候会显得代码很冗余, 而 CBV 就很好的解决了这些问题. 并且 Django 官方在后面的 Django 版本中加入了很多基于 CBV 的类, 方便我们快速开发. 我们先简单的看下 Django 在中路由规则的是怎么定义的, 再粗略的看下一 FBV, 然后再讲下我们今天的重点 CBV.
1,Django 中路由规则的定义, 没有仔细读源码, 简单的讲一下
从这里进入 url 的定义:
这是源码
从源码可以看出, 我们在定义路由规则时, 第一个参数应该传入一个正则表达式, 第二个参数传入的就是 view, 从下面的处理逻辑看, view 的类型可以用两种. 第一种是 list 或 tuple 但这种是用来处理 include(......)导入的 url 的, 第二种类型就是 callable 类型的也就是可执行的即函数所以我们在写 FBV 的时候一定不要写上带上括号, 因为 url()函数需要的是一个可执行对象. 如果传入这两种以外的类型就会报错. 我们知道其实 include 导入 的其实也是一个 callable 类型的. 所以我们可以确定 view 本质上传入的是一个可执行的对象, 在启动服务时程序读取路由将 view 函数载入内存, 接受到请求的时候就会执行这 view 函数并且返回数据. 理解这一点很重要, 这个是 FBV 和 CBV 的基础.
2,FBV 中视图的定义和 url 的写法
FBV(基于函数的视图), 定义一个函数根据请求方法的不同而作出相应的处理, 注意重点是将对请求的处理封装在一个函数中. 看下例子
view.py
定义了一个 login 函数通过判断请求的方法进行返回
url.py
将 app01 中的 views 文件导入并将 login 方法传给 url 实现了一个 FBV
3,CBV 中视图的定义和 url 的写法
CBV(基于类的视图), 定义一个类, 继承 django.views.View, 将处理各种请求方式的逻辑用方法名加处理逻辑封装在方法里面, 注意重点是将请求的处理封装在类里面
- eg:
- form dajngo.views import VIew
- class Cbv(View):
- def a(self, params):
- pass
- def b(self, params):
- pass
- def get(self, request, *args, **kwargs):
- pass
- def post(self, request, *args, **kwargs):
- pass
- def put(self, request, *args, **kwargs):
- pass
看下例子:
view.py 视图的定义
url.py 路由的写法
4, 分析 3 中的调用过程
在 Django 项目启动时路由规则开始载入内存当程序读到 url(r'^cbv/', views.Cbv.as_View())时重点来了, views.Cbv 是我们自己定义的一个对象当我们. as_view()的时候就执行了父类的静态函数 as_view 方法 (根据面向对象的特性可以知道是调用的父类的), 我们可以根据在 1 中得出的结论. as_view() 返回的一定是个可调用对象
看下源码中 as_view 函数的定义:
可以看到, as_view 方法正如我们想的那样返回的是个可调用对象 view, 在路由规则载入内存后. as_view 的到的其实是个 view 方法, 在接受到请求是才会执行 view 方法, 而 view 方法的返回值是 self.dispatch(request, *args, **kwargs), 是由一个实例对象调用的 dispatch 方法, 我们怎么这个 self 是谁呢? 我们可以一层一层的往上拔从而确定这个实例对象是谁.
self.dispatch(request, *args, **kwargs)是由 view()方法调用的, view()方法又是由 as_view()方法调用的, as_view()方法又是由 views.Cbv 调用的, 所以我们可以确定 self 就是 Cbv 的实例对象, 但我们没有定义 dispatch 方法所以这个 dispatch 方法一定在 Views 类中有定义.
这就是父类中 dispatch 的定义, 先判断请求是否正确, 以 get 请求为例如果请求正确的话就就利用反射到 self 中去找与请求方式相对应的方法, 根据我们上面的分析 self 就是我们定义的类 Cbv,handler 就是我们定义的 get 方法最后 return 我们定义的 get 方法的返回值. 一层一层的向上冒泡, get 方法将返回值给 dispatch,dispatchs 再将返回值给 view, 到了 view 这层就和 FBV 一样了.
来源: http://www.bubuko.com/infodetail-2869354.html