使用

关于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源码解析的更多相关文章

  1. django中CBV源码分析

    前言:Django的视图处理方式有两种: FBV(function base views) 是在视图里基于函数形式处理请求. CBV(class base views)是在视图里基于类的形式处理请求. ...

  2. Django之CBV源码解析

    l链接跳转:https://www.cnblogs.com/hnlmy/p/9662798.html 以及https://www.cnblogs.com/hnlmy/p/10603999.html

  3. Django生命周期 URL ----> CBV 源码解析-------------- 及rest_framework APIView 源码流程解析

    一.一个请求来到Django 的生命周期   FBV 不讨论 CBV: 请求被代理转发到uwsgi: 开始Django的流程: 首先经过中间件process_request (session等) 然后 ...

  4. django之admin源码解析

    解析admin的源码 第一步:项目启动,加载settings文件中的 INSTALLED_APPS 里边有几个app就加载几个,按照注册顺序来执行. 第二步:其中加载的是admin.py,加载每一个a ...

  5. 2) 接口规范 原生django接口、单查群查 postman工具 CBV源码解析

    内容了解 """ .接口:什么是接口.restful接口规范 .CBV生命周期源码 - 基于restful规范下的CBV接口 .请求组件.解析组件.响应组件 .序列化组件 ...

  6. CBV源码解析

    1.CBV(class based view) 首先定义一个视图函数,用类的方式定义: 举例: class LoginView(View): def get(self,request): return ...

  7. sklearn中MLPClassifier源码解析

    神经网络 .fit() 首先传入类私用方法._fit() 确定hidden_layer_size是可迭代的 调用_validate_hyperparameters验证超参数是否合法 验证输入的x和y是 ...

  8. Django中CBV及其源码解释

    FBV(function base views) 就是在视图里使用函数处理请求. CBV(class base views) 就是在视图里使用类处理请求. Python是一个面向对象的编程语言,如果只 ...

  9. CBV源码与APIView源码解析

    一.CBV源码解析 在我们写cbv的时候在url中和fbv的区别就是是否调用了as_view()方法,所以关键入手点就是这个方法 @classonlymethod # 这是类的绑定方法,这个cls是我 ...

随机推荐

  1. OFTP简介

    OFTP协议由欧洲汽车标准组织Odette创建,第一个版本于1986年发布,旨在用于当时可用的网络服务,主要是X.25服务.Odette还考虑到VAN(增值网络)服务可能是通信链的一部分.OFTP是汽 ...

  2. 修改Dreamweaver CC 2017 代码背景颜色

    Windows系统路径: E:\Program Files\Adobe\Dreamweaver CC\www\extensions\default\LightTheme\main.less (如果用的 ...

  3. MySql 三大知识点——索引、锁、事务

    1. 索引 索引,类似书籍的目录,可以根据目录的某个页码立即找到对应的内容. 索引的优点:1. 天生排序.2. 快速查找.索引的缺点:1. 占用空间.2. 降低更新表的速度. 注意点:小表使用全表扫描 ...

  4. Python中的string模块的学习

    代码为主,相信有python基础的都能看懂: ? [python] view plain copy >>> import string   >>> string.a ...

  5. Python的浮点数损失精度问题

    本篇讨论的现象可以从下面这段脚本体现出来: >>> x = 0.0 >>> for i in range(10): x += 0.1 print(x) 0.1 0. ...

  6. Groovy 和 Gradle

    0.Groovy和Gradle是什么关系? Gradle,自动化构建工具,通过简单编写Groovy脚本,便可进行依赖管理并完成项目构建: 1. Groovy有什么用? 脚本+Java代码: 2. Gr ...

  7. 简化实现动态行列转置的SQL

    动态行列转换的计算在实际业务中非经常见,网上各类技术论坛上都有讨论,比方以下这些问题: http://www.iteye.com/problems/87788 http://bbs.csdn.net/ ...

  8. mysqldump定时备份数据库

    mysql服务器ip:192.168.0.10 备份服务器ip:192.168.0.11 数据库名称:db_product 思路:在mysql服务器A上创建一个用户分配权限专门用于数据库备份,A服务器 ...

  9. Windows 安装服务 的两种方式

    第一种   -  安装服务时自定义服务名称:(注意 binpath= 和路径之间的那个空格)sc create 服务名称  binpath= "D:\Service.exe" di ...

  10. 导出jqgrid表格数据为EXCEL文件,通过tableExport.js插件。

    今天公司项目需要做个导出功能,将jqgrid查询出的数据导出为EXCEL表格文件,期间遇到两个问题: 1.导出报错 uncaught exception: INVALID_CHARACTER_ERR: ...