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是我 ...
随机推荐
- HADOOP security
https://www.microsoft.com/en-us/trustcenter/security/azure-security https://docs.microsoft.com/en-us ...
- android sdk content loader 0%不动
Make sure that eclipse is not active. If it is active kill eclipse from the processes tab of the tas ...
- Zookeeper —— 初识
什么是 Zookeeper Zookeeper 是一个开放源代码的分布式协调服务,由雅虎创建,是 Google Chubby 的开源实现: Zookeeper 是典型的分布式数据一致性的解决方案,分布 ...
- 明天软软onsite
现在在飞机上,还有1.5小时到达.买了网络包,速度不错.今年上半年第三次飞西雅图,过几天也许还有第四次... 今天群主FB加面系统设计非常顺利,祝他拿到大包裹,也希望拿到以后发大红包,这回我一定不能错 ...
- java生成兑换码礼包码--工具类
import java.util.HashSet; import java.util.Random; import java.util.Set; public class GenSerial { pr ...
- mybatis generator 为数据库保留字段 转义
为order 添加转义符号“ ` ” `order` <property name="autoDelimitKeywords" value="true"& ...
- laravel项目安装
composer install 遇到的问题 composer.json 里有多余的逗号 没有打开php_openssl.php_fileinfo 报错没具体报错信息,修改配置文件 config\ap ...
- JAVA并发编程——守护线程(Daemon Thread)
在Java中有两类线程:用户线程 (User Thread).守护线程 (Daemon Thread). 所谓守护 线程,是指在程序运行的时候在后台提供一种通用服务的线程,比如垃圾回收线程就是一个很称 ...
- c# httpclient
using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System ...
- 算法-KMP
KMP算法的作用在于在一个主串中查找一个主串. 传统查找子串的方法是一个字符一个字符的比较,代码如下: public static int notKMP(String main,String sub) ...