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是我 ...
随机推荐
- 如何保持github的fork于主干同步
step1: https://help.github.com/articles/configuring-a-remote-for-a-fork/ step2: https://help.github. ...
- ELK & ElasticSearch 5.1 基础概念及配置文件详解【转】
转自:https://blog.csdn.net/zxf_668899/article/details/54582849 配置文件 基本概念 接近实时NRT 集群cluster 索引index 文档d ...
- redis的事务不是原子性
Reference: https://blog.csdn.net/u011692780/article/details/81213010 一.事务的四大特性 关系型数据库的事务具有四个特性: 1. 原 ...
- 码云git 使用配置
码云git 使用配置:www.gitee.com安装:1.Git-2.18.0-64-bit.exe:2.GitExtensions-2.51.04.msi:3.GitExtensionsVSIX.v ...
- SpringBoot2.X + SpringCache + redis解决乱码问题
环境:SpringBoot2.X + SpringCache + Redis Spring boot默认使用的是SimpleCacheConfiguration,使用ConcurrentMapCach ...
- es中queryBuilders api
package com.elasticsearch; import org.elasticsearch.action.ActionListener; import org.elasticsearch. ...
- Day8 函数指针做函数参数
课堂笔记 课程回顾 多态 virtual关键字 纯虚函数 virtual func() = 0; 提前布局vptr指针 面向接口编程 延迟绑定 多态的析构函数的虚函数. ...
- PHP memcached memcache 扩展安装
好久没配置环境今天安装PHP 开发环境, 项目比较老,一开始以为项目用的是memcache 装完后发现 项目用的是memcached 所以正好两个都装了. 碰到些坑希望能帮助到百度到这篇文章的伙伴 . ...
- JavaCC从入门到出门
一.JavaCC JavaCC是java的compiler compiler.JavaCC是LL解析器生成器,可处理的语法范围比较狭窄,但支持无限长的token超前扫描. 安装过程: 我是从githu ...
- Golang, 以 9 个简短代码片段,弄懂 defer 的使用特点
作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...