Django中CBV源码解析
使用
关于FBV和CBV的使用在之前有提到,点击穿越。
准备
首先在视图中创建一个类并继承 django.views.View 类,在类中可定义各种请求方式对应执行的函数(函数名为请求方式名称小写)。
from django.views import View class TestView(View):
def get(self, request):
return HttpResponse('get') def post(self, request):
return HttpResponse('post')
配置路由。
from django.conf.urls import url
from app import views
urlpatterns = [
url(r'^test/', views.TestView.as_view()),
]
源码
做好上述准备之后,就可以通过相应的请求方法请求对应路由地址来执行CBV视图中对应请求方法名的函数,为什么Django能帮我们做到这一点呢?我们知道,在使用FBV时,路由地址对应的是一个函数句柄,而在CBV中,路由地址对应的是视图类的 as_view 函数的执行结果。例如:
from django.conf.urls import url
from app import views def test():
pass urlpatterns = [
url(r'^test_FBV/', test),
url(r'^test_CBV/', views.TestView.as_view()),
]
所以从这里就可以看出, as_view 函数的返回值一定也是一个函数句柄。查看as_view()函数源码:
 class View(object):
     @classonlymethod
     def as_view(cls, **initkwargs):
         for key in initkwargs:
             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__))
             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 = cls(**initkwargs)
             if hasattr(self, 'get') and not hasattr(self, 'head'):
                 self.head = self.get
             self.request = request
             self.args = args
             self.kwargs = kwargs
             return self.dispatch(request, *args, **kwargs)
         view.view_class = cls
         view.view_initkwargs = initkwargs
         update_wrapper(view, cls, updated=())
         update_wrapper(view, cls.dispatch, assigned=())
         return view
直接看 29 行, as_view 函数的返回值其实就是 15 行定义的 view 函数。也就是说当请求对应地址时,实际上执行的是这个 view 函数,
从 17 、 18 行可以看出,当我们在视图类中定义了 get 函数而没有定义 head 函数时,就定义一个 head 函数指向了 get 函数。也就是说当只定义了 get 函数而以 head 方式请求时,会执行 get 函数。
再看 22 行, view 函数的返回值其实是 dispatch 函数的执行结果,看源码:
class View(object):
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_allowed
return handler(request, *args, **kwargs)
我们会发现,dispatch方法很简单,就是判断当前请求方法名称是否包含在 http_method_names 这个列表中。如果包含,则通过 getattr 从当前视图类实例中获取该方法名称函数句柄赋值给 handler ,最后执行。也就是说如果请求方式为 put ,就会调用视图类中的 put 函数;如果请求方式为 patch ,就会调用视图类中的 patch 函数。
Django中CBV源码解析的更多相关文章
- django中CBV源码分析
		前言:Django的视图处理方式有两种: FBV(function base views) 是在视图里基于函数形式处理请求. CBV(class base views)是在视图里基于类的形式处理请求. ... 
- Django之CBV源码解析
		l链接跳转:https://www.cnblogs.com/hnlmy/p/9662798.html 以及https://www.cnblogs.com/hnlmy/p/10603999.html 
- Django生命周期  URL ----> CBV 源码解析-------------- 及rest_framework APIView 源码流程解析
		一.一个请求来到Django 的生命周期 FBV 不讨论 CBV: 请求被代理转发到uwsgi: 开始Django的流程: 首先经过中间件process_request (session等) 然后 ... 
- django之admin源码解析
		解析admin的源码 第一步:项目启动,加载settings文件中的 INSTALLED_APPS 里边有几个app就加载几个,按照注册顺序来执行. 第二步:其中加载的是admin.py,加载每一个a ... 
- 2) 接口规范  原生django接口、单查群查  postman工具 CBV源码解析
		内容了解 """ .接口:什么是接口.restful接口规范 .CBV生命周期源码 - 基于restful规范下的CBV接口 .请求组件.解析组件.响应组件 .序列化组件 ... 
- CBV源码解析
		1.CBV(class based view) 首先定义一个视图函数,用类的方式定义: 举例: class LoginView(View): def get(self,request): return ... 
- sklearn中MLPClassifier源码解析
		神经网络 .fit() 首先传入类私用方法._fit() 确定hidden_layer_size是可迭代的 调用_validate_hyperparameters验证超参数是否合法 验证输入的x和y是 ... 
- Django中CBV及其源码解释
		FBV(function base views) 就是在视图里使用函数处理请求. CBV(class base views) 就是在视图里使用类处理请求. Python是一个面向对象的编程语言,如果只 ... 
- CBV源码与APIView源码解析
		一.CBV源码解析 在我们写cbv的时候在url中和fbv的区别就是是否调用了as_view()方法,所以关键入手点就是这个方法 @classonlymethod # 这是类的绑定方法,这个cls是我 ... 
随机推荐
- 使用git和github进行协同开发流程
			(本文假设各位已经对基本git的基本概念.操作有一定的理解,如无相关git知识,可以参考Pro Git这本书进行相关的学习和练习) 很多项目开发都会采用git这一优秀的分布式版本管理工具进行项目版本管 ... 
- 【计算机网络】OSI七层模型图解
			1.物理层 建立.维护.断开物理连接.(由底层网络定义协议) 2.数据链路层 建立逻辑连接.进行硬件地址寻址.差错校验等功能.(由底层网络定义协议) 将比特组合成字节进而组合成帧,用MAC地址访问介质 ... 
- 【iCore4 双核心板_ARM】例程二十五:LWIP_DNS实验——域名解析
			实验现象: 核心代码: int main(void) { system_clock.initialize(); led.initialize(); adc.initialize(); delay.in ... 
- IE8 下更改input[file] file文件选择框样式
			1/使用绝对定位,将文件选择框固定,并且隐藏该选择框(文件选择框可调整宽高),设置该文件选择框 z-index 调高 比如 999. 2/使用任意标签,调整为与上面选择框相同宽高,目的为使用该标签样式 ... 
- 微信小程序——购物车结算
			项目需要做个购物车结算功能,先分析需求: 1.全选,反选的功能.当选中的个数 = 购物车的数量时,勾选全选按钮,反之则取消选中全选按钮: 2.改变选中状态时,计算总价和总数量: 3.单个产品的数量加减 ... 
- Linux 相关术语_002
			Linux(Linux is not unix)是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统. 它能运行主要的UNIX工 ... 
- springboot-async
			在项目中,当访问其他人的接口较慢或者做耗时任务时,不想程序一直卡在耗时任务上,想程序能够并行执行, 我们可以使用多线程来并行的处理任务,也可以使用spring提供的异步处理方式@Async. Spri ... 
- spring-boot项目建立
			使用idea来开发spring-boot项目,对于community版本的idea,由于没有spring-boot插件,所有对于开发spring-boot的web项目来说不是很方便,所以安装Ultim ... 
- 一个第三方Dart库导致的编译错误!
			今天学习flutter过程中,突然程序不能运行了,无论是命令行,抑或Android Studio,还是Idea都是出现同样错误,如下: Running .5s Launching lib\main.d ... 
- JS数组常用方法总结
			JavaScript中创建数组有两种方式 (一)使用 Array 构造函数: var arr1 = new Array(); //创建一个空数组 var arr2 = new Array(20); / ... 
