FBV

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

在之前django的学习中,我们一直使用的是这种方式,所以不再赘述。

CBV

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

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

  1. 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
  2. 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性

使用class-based views

如果我们要写一个处理GET方法的view,用函数写的话是下面这样。

from django.http import HttpResponse

def my_view(request):
if request.method == 'GET':
return HttpResponse('OK')

如果用class-based view写的话,就是下面这样

from django.http import HttpResponse
from django.views import View class MyView(View): def get(self, request):
return HttpResponse('OK')

Django的url是将一个请求分配给可调用的函数的,而不是一个class。针对这个问题,class-based view提供了一个as_view()静态方法(也就是类方法),调用这个方法,会创建一个类的实例,然后通过实例调用dispatch()方法,dispatch()方法会根据request的method的不同调用相应的方法来处理request(如get() , post()等)。到这里,这些方法和function-based view差不多了,要接收request,得到一个response返回。如果方法没有定义,会抛出HttpResponseNotAllowed异常。

在url中,就这么写:

# urls.py
from django.conf.urls import url
from myapp.views import MyView urlpatterns = [
url(r'^index/$', MyView.as_view()),
]

类的属性可以通过两种方法设置,第一种是常见的Python的方法,可以被子类覆盖。

from django.http import HttpResponse
from django.views import View class GreetingView(View):
name = "yuan"
def get(self, request):
return HttpResponse(self.name) # You can override that in a subclass class MorningGreetingView(GreetingView):
name= "alex"

第二种方法,你也可以在url中指定类的属性:

在url中设置类的属性Python

urlpatterns = [
url(r'^index/$', GreetingView.as_view(name="egon")),
]

使用Mixin

我觉得要理解django的class-based-view(以下简称cbv),首先要明白django引入cbv的目的是什么。在django1.3之前,generic view也就是所谓的通用视图,使用的是function-based-view(fbv),亦即基于函数的视图。有人认为fbv比cbv更pythonic,窃以为不然。python的一大重要的特性就是面向对象。而cbv更能体现python的面向对象。cbv是通过class的方式来实现视图方法的。class相对于function,更能利用多态的特定,因此更容易从宏观层面上将项目内的比较通用的功能抽象出来。关于多态,不多解释,有兴趣的同学自己Google。总之可以理解为一个东西具有多种形态(的特性)。cbv的实现原理通过看django的源码就很容易明白,大体就是由url路由到这个cbv之后,通过cbv内部的dispatch方法进行分发,将get请求分发给cbv.get方法处理,将post请求分发给cbv.post方法处理,其他方法类似。怎么利用多态呢?cbv里引入了mixin的概念。Mixin就是写好了的一些基础类,然后通过不同的Mixin组合成为最终想要的类。

所以,理解cbv的基础是,理解Mixin。Django中使用Mixin来重用代码,一个View Class可以继承多个Mixin,但是只能继承一个View(包括View的子类),推荐把View写在最右边,多个Mixin写在左边。

回顾多重继承和Mixin

多重继承

回忆一下Animal类层次的设计,假设我们要实现以下4种动物:

  • Dog - 狗狗;
  • Bat - 蝙蝠;
  • Parrot - 鹦鹉;
  • Ostrich - 鸵鸟。

如果按照哺乳动物和鸟类归类,我们可以设计出这样的类的层次:

但是如果按照“能跑”和“能飞”来归类,我们就应该设计出这样的类的层次:

如果要把上面的两种分类都包含进来,我们就得设计更多的层次:

  • 哺乳类:能跑的哺乳类,能飞的哺乳类;
  • 鸟类:能跑的鸟类,能飞的鸟类。

这么一来,类的层次就复杂了:

如果要再增加“宠物类”和“非宠物类”,这么搞下去,类的数量会呈指数增长,很明显这样设计是不行的。

正确的做法是采用多重继承。首先,主要的类层次仍按照哺乳类和鸟类设计:

class Animal(object):
pass # 大类:
class Mammal(Animal):
pass class Bird(Animal):
pass # 各种动物:
class Dog(Mammal):
pass class Bat(Mammal):
pass class Parrot(Bird):
pass class Ostrich(Bird):
pass

现在,我们要给动物再加上RunnableFlyable的功能,只需要先定义好RunnableFlyable的类:

class Runnable(object):
def run(self):
print('Running...') class Flyable(object):
def fly(self):
print('Flying...'

对于需要Runnable功能的动物,就多继承一个Runnable,例如Dog

class Dog(Mammal, Runnable):
pass

对于需要Flyable功能的动物,就多继承一个Flyable,例如Bat

class Bat(Mammal, Flyable):
pass

通过多重继承,一个子类就可以同时获得多个父类的所有功能。

Mixin

在设计类的继承关系时,通常,主线都是单一继承下来的,例如,Ostrich继承自Bird。但是,如果需要“混入”额外的功能,通过多重继承就可以实现,比如,让Ostrich除了继承自Bird外,再同时继承Runnable。这种设计通常称之为Mixin。

为了更好地看出继承关系,我们把RunnableFlyable改为RunnableMixinFlyableMixin。类似的,你还可以定义出肉食动物CarnivorousMixin和植食动物HerbivoresMixin,让某个动物同时拥有好几个Mixin:

class Dog(Mammal, RunnableMixin, CarnivorousMixin):
pass

Mixin的目的就是给一个类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个Mixin的功能,而不是设计多层次的复杂的继承关系。

Python自带的很多库也使用了Mixin。举个例子,Python自带了TCPServerUDPServer这两类网络服务,而要同时服务多个用户就必须使用多进程或多线程模型,这两种模型由ForkingMixinThreadingMixin提供。通过组合,我们就可以创造出合适的服务来。

比如,编写一个多进程模式的TCP服务,定义如下:

class MyTCPServer(TCPServer, ForkingMixin):
pass

编写一个多线程模式的UDP服务,定义如下:

class MyUDPServer(UDPServer, ThreadingMixin):
pass

如果你打算搞一个更先进的协程模型,可以编写一个CoroutineMixin

class MyTCPServer(TCPServer, CoroutineMixin):
pass

这样一来,我们不需要复杂而庞大的继承链,只要选择组合不同的类的功能,就可以快速构造出所需的子类。

小结

由于Python允许使用多重继承,因此,Mixin就是一种常见的设计。只允许单一继承的语言(如Java)不能使用Mixin的设计。

Django的CBV与FBV的更多相关文章

  1. Django之CBV和FBV

    Django之CBV和FBV CBV和FBV是C和F的区别: C是Class,F是Function 在请求中,有GET请求和POST请求. 在写CBV时,url是可以对应一个类的,在类中,分别写出GE ...

  2. django补充CBV和FBV模式

    django补充CBV和FBV模式FBV模式---函数:经常用的方式CBV模式---类CBV中url连接时函数名后面要接.as_view()class index(views.View): @... ...

  3. Django(视图 CBV、FBV)

    day67 参考:http://www.cnblogs.com/liwenzhou/articles/8305104.html CBV和FBV 我们之前写过的都是基于函数的view,就叫FBV.还可以 ...

  4. Django的 CBV和FBV

    FBV CBV 回顾多重继承和Mixin 回到顶部 FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以 ...

  5. django视图 CBV 和 FBV

    目录 视图 CBV 和 FBV 什么是视图? FBV function based view 基于函数的视图 CBV class based view 基于类的视图 小技巧 CBV 如何获取页面请求类 ...

  6. Django之 CBV和FBV

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

  7. Django的CBV和FBV

    一.FBV FBV(function base views) 就是在视图里使用函数处理请求,也是我们最开始接触和使用的方式,普通项目中最常见的方式. urls.py 1 2 3 4 urlpatter ...

  8. python测试开发django-73.django视图 CBV 和 FBV

    前言 FBV(function base views) 就是在视图里使用函数处理请求,这一般是学django入门的时候开始使用的方式. CBV(class base views) 就是在视图里使用类处 ...

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

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

随机推荐

  1. ExifInterface针对照片的使用

    ExifInterface是保存照片信息的,那么我们在有需要的时候就可以通过这类,来获取照片的一些数码参数来做适当来逻辑处理,比较典型的案例就是android有的机型拍照或者选择照片后,照片可能会被旋 ...

  2. ios学习笔记图片+图片解释(c语言 oc语言 ios控件 ios小项目 ios小功能 swift都有而且笔记完整喔)

    下面是目录其中ios文件夹包括了大部分ios控件的介绍和演示,swift的时完整版,可以学习完swift(这个看的是swift刚出来一周的视频截图,可能有点赶,但是完整),c语言和oc语言的也可以完整 ...

  3. 自定义IPython Qt Console 窗口大小、字体、颜色

    windows下将IPython Qt Console的快捷方式修改为: "C:\Python\IPython Qt Console.exe" --ConsoleWidget.fo ...

  4. 谈谈SQL server的 worker threads-----微软亚太区数据库技术支持组 官方博客

    https://blogs.msdn.microsoft.com/apgcdsd/2012/11/27/sql-server-worker-threads/

  5. dubbo知识点理解2

    作者:网易云链接:https://www.zhihu.com/question/45413135/answer/226794957来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  6. 解析天气预报JSON数据

    解析天气预报JSON数据 JSON字符串 constjson2 = '{' + #13#10 +'"error":0,' + #13#10 +'"status" ...

  7. 初识小米Minos

    1. Minos框架的基本介绍 小米公司不仅仅在搞手机以及MIUI rom的研发工作,云计算.虚拟化以及Hadoop也是小米现在在搞的东西,小米与2012年下半年成立了自己的Hadoop团队.介绍小米 ...

  8. 解决kylin build cube第一步报错:java.lang.NullPointerException

    报错栈: -- ::, ERROR [pool--thread-] threadpool.DefaultScheduler: : ExecuteException job:933bc47a-302c- ...

  9. BP反向传播算法的工作原理How the backpropagation algorithm works

    In the last chapter we saw how neural networks can learn their weights and biases using the gradient ...

  10. iOS:使用贝塞尔曲线绘制图表(折线图、柱状图、饼状图)

    1.介绍: UIBezierPath :画贝塞尔曲线的path类 UIBezierPath定义 : 贝赛尔曲线的每一个顶点都有两个控制点,用于控制在该顶点两侧的曲线的弧度. 曲线的定义有四个点:起始点 ...