Django中CBV及其源码解释
FBV(function base views) 就是在视图里使用函数处理请求。
CBV(class base views) 就是在视图里使用类处理请求。
Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:
- 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
- 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
CBV源码解析:
首先,在urls中,我们会有这样一个访问函数:
path('login/',views.LoginView.as_view() )
当访问login时,django会调用 views.LoginView.as_view() 中 as_view() 这个函数,那么必须先要去看看LoginView中该函数构成:
class LoginView(View):
def get(self,request): return render(request,"login.html")
def post(self,request): return HttpResponse("Hello")
LoginView 是我们在视图中创建的类,继承View,LoginView 没有as_view这个方法,于是我们来到继承的父类View,并找到as_view
@classonlymethod
def as_view(cls, **initkwargs):
"""Main entry point for a request-response process."""
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 # take name and docstring from class
update_wrapper(view, cls, updated=()) # and possible attributes set by decorators
# like csrf_exempt from dispatch
update_wrapper(view, cls.dispatch, assigned=())
return view
从源码中可以看到as_view最后返回了一个view
此时
path('login/',views.LoginView.as_view() ) ------->>>> path('login/',View.view )
当有用户登录Login页面时,dajango会自动调用 View.view
又找到view的方法,源码如下:
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方法:
self = cls(**initkwargs) cls为调用as_view时传入的类,为调用该类的对象 LoginView ,这里self为 LoginView 的实例对象.
return self.dispatch(request, *args, **kwargs) 最后返回的时候,先调用了self.dispatch(request, *args, **kwargs)这个方法.而cls就是LoginView ,一步步找到
dispatch这个方法
dispatch源码(分发):
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
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)
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
其中
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
获取反射获取到对应的方法('get', 'post', 'put'....)
最后返回:handler(request, *args, **kwargs) 的调用结果,完成分发
self.http_method_not_allowed 为错误或找不到值时报错调用的方法
更多可以查看
Django中CBV及其源码解释的更多相关文章
- django中CBV源码分析
前言:Django的视图处理方式有两种: FBV(function base views) 是在视图里基于函数形式处理请求. CBV(class base views)是在视图里基于类的形式处理请求. ...
- Python Django中QQ邮箱授权码问题
Python Django中QQ邮箱授权码问题 系统及软件版本如下: Ubuntu Kylin 16.04 Python 3.5.1 Django 1.9.7 PyCharm Community Ed ...
- django中CBV
08.13自我总结 django中CBV 一.django处理业务逻辑的两种方式 FBV (function based views):使用函数来处理业务逻辑 CBV (class based vie ...
- Django中CBV的执行顺序之源码解析
浅析Django中的CBV的执行顺序 下图为CBV方式的执行顺序,大概执行流程如下: 其中浅蓝色为在假设自己写的类,即Test类中没有dispatch方法的情况下的执行顺序,当自己的类中有dispat ...
- Django中CBV源码解析
使用 关于FBV和CBV的使用在之前有提到,点击穿越. 准备 首先在视图中创建一个类并继承 django.views.View 类,在类中可定义各种请求方式对应执行的函数(函数名为请求方式名称小写). ...
- Django中CBV(Class Base Views)模型源码分析
在view文件中编写一个类,并配置好路由 class Test(View): def get(self, request, *args, **kwargs): return HttpResponse( ...
- Django中CBV View的as_view()源码解析
CBV与FBV路由区别 urlpatterns = [ url(r'^publish/$', views.Publishs.as_view()), # CBV写法 url(r'^publish/$', ...
- django中CBV加csrf_exempt函数问题
CSRF Token相关装饰器在CBV只能加到dispatch方法上 备注: 1. csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件. 2. c ...
- django 中CBV和FBV 路由写法的区别
使用视图函数时, FBV: django完成URL解析之后,会直接把request对象以及URL解析器捕获的参数(比如re_path中正则表达捕获的位置参数或关键字参数)丢给视图函数 CBV: 这些参 ...
随机推荐
- Docker 编排工具Rancher 1.6.18
使用docker获取rancher [root@localhost /]# docker pull rancher/server:stable [root@localhost /]# docker i ...
- C# DataTable.Compute()用法
DataTable.Compute()用法 2010-04-07 11:28 一.DataTable.Compute()方法說明如下 作用: 计算用来传递筛选条件的当前行上的给定表达 ...
- 题解——Codeforces Round #507 (based on Olympiad of Metropolises) T2(模拟)
T2还是模拟 枚举一下第一个放哪里 然后贪心的反转即可 虽然我也不会证,但是这题肯定有解qwq #include <cstdio> #include <algorithm> # ...
- es索引维护的常用帖子
Elasticsearch 新增字段
- [转载]哪个版本的gcc才支持c11
转自:https://blog.csdn.net/haluoluo211/article/details/71141093 哪个版本的gcc才支持c11 2017年05月03日 19:25:43 Fi ...
- nrf24l01 IRQ一直为高电平
测试发现发送数据时MCU卡住不动,测试发现卡在了 while(NRF24L01_IRQ!=0); 也就是说管脚IRQ一直是高电平.仔细排查发现nrf24l01处于接收模式,改为发送模式就好了 NRF2 ...
- wow.js
一.首先说明一下怎么使用这个插件: 1.wow.js依赖于animate.css,首先在头部引用animate.css或者animate.min.css. <link rel="sty ...
- CZK 的饮料店
[题目描述] 一天,小学生 cyx 向你请教了一道他不会做的小学数学题,你瞄了一眼题目,发现题目长下面这样. czk 老板开了个饮料连锁店,连锁店共有 n 家,出售的饮料种类相同. 为了促销,czk ...
- Android AndFix修复方式的限制
这里阅览了很多网上关于修复的资料,一一贴在这里便于查看: https://github.com/alibaba/AndFix 这是官方处 要了解使用,一定得看看这里. http://www.jia ...
- DP入门基本问题
个人对简单的dp问题的理解:找是否有重叠问题,明确递推关系,怎么推的(顺序千万不要搞错),找到状态方程,循环时注意边界条件和方程式是否严格成立. 转自:https://www.cnblogs.com/ ...