目录
FBV和VBC
CBV和FBV
CBV源码分析
CBV源码简述
FBV和VBC
一个视图函数(类),简称视图, 是一个简单的python函数(类),他接受web请求并且返回web响应.
响应可以是一张网页的HTML内容, 一个重定向, 一个404错误, 一个xml文档或者一张图片.
无论视图本身包含什么逻辑, 都要返回响应. 代码写在哪里也无所谓,只要他在你当前项目目录下. 除此之外没有更多的要求了, 为了将代码放在某处, 大家约定俗成将视图放置在项目project或者应用程序app目录中名为views.py的文件中
CBV和FBV
FBV function base view: 基于函数的视图
CBV class base view : 基于类的视图
FBV版添加班级
def add_class(request):if request.method == 'POST':class_name = request.POST.get('class_name')models.Classes.objects.create(name=class_name)return redirect('/class_list/')return render(request,'add_class.html')
CBV版本添加班级
CBV需要继承view类
from django.views import Viewclass AddClass(View):def get(self, request):return render(request,add_class.html')def post(self, request):class_name = request.POST.get('class_name')models.Class.objects.create(name=class_name)return redirect('/class_list/')
使用CBV时, urls.py中也做对应的修改
url(r'^add_class/$', views.AddClass.asview()),
基于CBV 与FBV的不同之处来分析CBV的运行原理
CBV源码分析

首先, as_view()是一个绑定给类的方法
其次, 由于url中是加上括号调用了as_view(), 所以,观察返回值能够发现, 返回的是内部的一个view函数
也就是说 AddClass.as_view() 运行的结果是view, 所以views.AddClass.as_view() = views.view
url(r'^add_class/$',views.vies),
所以, CBV路由匹配的本质就是FBV
接下来我们分析一下, 当路由匹配成功时, 需要执行的这个view函数的源码
from django.views import Viewclass AddClass(View):def get(self,request):return render(request,'add_class.html')def post(self, request):class_name = request.POST.get('class_name')models.Classes.objects.create(name=class_name)return redirect('/class_list/')
@classonlymethoddef as_view(cls,**initkwargs):...def view(request,*args,**kwargss):self = cls(**initkwargs) >>>实例化生成一个对象if hasattr(self, 'get') and not hasattr(self,'head'):self.request = self.get >>> 给生成的对象添加 head属性self.request = request >>> 给生成的对象添加 request 属性self.args = args >>> 给生成的对象添加 args 属性self.kwargs = kwargs >>> 给生成的对象添加kwargs属性return self.dispatch(request,*args,**kwargs)...return view
最为重要的部分就是 return self.dispatch(request,*args,**kwargs)
由于对象和产生对象的AddClass类中都没有dispatch函数, 所以需要到AddClass的父类view中去找
[类的名称空间查找顺序>>> 对象自身>>父类>>父类的父类]
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']def dispatch(self, request, *args, **kwargs):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_allowedreturn handler(request, *args, **kwargs)
判断当前请求的方法是否符合8个默认的请求方法
getattr(对象, 请求的方法(字符串),那不到请求方法的报错信息) >> 拿到了AddClass我们自己定义的类的get方法
最后一步就是执行了我们自定义的get方法
CBV源码简述
根据前端请求方式的不同自动匹配执行对应的方法-在url路由中的views.类 名.as_view()的源码下可以 看到是被@classonlymethod修饰的类方法,内部定义闭包函数传参并返回闭包函数名、在dajong启动的时候会执行urls 的as_view()产生变形为views.view,在浏览器提交请求的时候就会触发view方法,通过view下的self 使用类的对 象,返回self.dispatch属性、在父类中的dispathc函数通过反射机制就 通过字符串操作对象属性口只有在被完成后才 会真正执行,就是可以事先写好逻辑接口,事后实现接口功能


















