FBV(function base views) 就是在视图里使用函数处理请求。

CBV(class base views) 就是在视图里使用类处理请求。

Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:

  1. 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
  2. 可以用不同的函数针对不同的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及其源码解释的更多相关文章

  1. django中CBV源码分析

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

  2. Python Django中QQ邮箱授权码问题

    Python Django中QQ邮箱授权码问题 系统及软件版本如下: Ubuntu Kylin 16.04 Python 3.5.1 Django 1.9.7 PyCharm Community Ed ...

  3. django中CBV

    08.13自我总结 django中CBV 一.django处理业务逻辑的两种方式 FBV (function based views):使用函数来处理业务逻辑 CBV (class based vie ...

  4. Django中CBV的执行顺序之源码解析

    浅析Django中的CBV的执行顺序 下图为CBV方式的执行顺序,大概执行流程如下: 其中浅蓝色为在假设自己写的类,即Test类中没有dispatch方法的情况下的执行顺序,当自己的类中有dispat ...

  5. Django中CBV源码解析

    使用 关于FBV和CBV的使用在之前有提到,点击穿越. 准备 首先在视图中创建一个类并继承 django.views.View 类,在类中可定义各种请求方式对应执行的函数(函数名为请求方式名称小写). ...

  6. Django中CBV(Class Base Views)模型源码分析

    在view文件中编写一个类,并配置好路由 class Test(View): def get(self, request, *args, **kwargs): return HttpResponse( ...

  7. Django中CBV View的as_view()源码解析

    CBV与FBV路由区别 urlpatterns = [ url(r'^publish/$', views.Publishs.as_view()), # CBV写法 url(r'^publish/$', ...

  8. django中CBV加csrf_exempt函数问题

    CSRF Token相关装饰器在CBV只能加到dispatch方法上 备注: 1. csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件. 2. c ...

  9. django 中CBV和FBV 路由写法的区别

    使用视图函数时, FBV: django完成URL解析之后,会直接把request对象以及URL解析器捕获的参数(比如re_path中正则表达捕获的位置参数或关键字参数)丢给视图函数 CBV: 这些参 ...

随机推荐

  1. 如何在gvim中安装autoproto自动显示函数原型

    cankao: http://www.vim.org/scripts/script.php?script_id=1553 注意, 在gvim中执行的命令, :foo和:!foo 的区别, 跟vim一样 ...

  2. HDU 4366 Successor(dfs序 + 分块)题解

    题意:每个人都有一个上司,每个人都有能力值和忠诚值,0是老板,现在给出m个询问,每次询问给出一个x,要求你找到x的所有直系和非直系下属中能力比他高的最忠诚的人是谁 思路:因为树上查询很麻烦,所以我们直 ...

  3. 如何创建并运行java线程 , 多线程使用

    http://www.importnew.com/20672.html https://www.cnblogs.com/wxd0108/p/5479442.html https://www.cnblo ...

  4. (转) Dissecting Reinforcement Learning-Part.2

    Dissecting Reinforcement Learning-Part.2 Jan 15, 2017 • Massimiliano Patacchiola 原文链接:https://mpatac ...

  5. 利用Spring Cloud实现微服务- 熔断机制

    1. 熔断机制介绍 在介绍熔断机制之前,我们需要了解微服务的雪崩效应.在微服务架构中,微服务是完成一个单一的业务功能,这样做的好处是可以做到解耦,每个微服务可以独立演进.但是,一个应用可能会有多个微服 ...

  6. springmvc上传zip文件并解压缩代码示例

    <input type="file"  id="file"  name="file"> spring中的配置: <!-- ...

  7. window下的Django入门

    一.window下新建安装(参考书籍:<python编程:从入门到实践>) 新建一个文件夹 learning_log ,在终端中切换到该目录下,并创建一个虚拟工作环境,运行模块 venv  ...

  8. forEach、map、filter、find、sort、some等易错点整理

    一.常用方法解析   说起数组操作,我们肯定第一反应就是想到forEach().map().filter()等方法,下面分别阐述一下各方法的优劣. 1.forEach 1.1 基础点   forEac ...

  9. _map

    地图属性控制表 comment 备注 Map 地图ID,.gps第一个参数 Zone 区域ID,.gps第二个参数,整个地图时填0 Area 地域ID,.gps第三个参数,整个地图或区域时填0 Cha ...

  10. codeforces 767C - Garland

    题目链接:http://codeforces.com/contest/767/problem/C 问能否将一棵带点权的书分成点权$3$块,求任意方案. 其实考虑一棵以$x$为根的子树权值为${\fra ...