V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
icecream187
V2EX  ›  Python

Django 的 class based views 比函数 views 对比,有哪些好处?有没有用 cbv 开发的例子?多谢。

  •  
  •   icecream187 · 2015-01-26 11:22:55 +08:00 · 5716 次点击
    这是一个创建于 3596 天前的主题,其中的信息可能已经有所发展或是发生改变。
    Django的class based views比函数views 对比,有哪些好处?有没有用cbv开发的例子?多谢。
    24 条回复    2015-01-26 15:22:08 +08:00
    virusdefender
        1
    virusdefender  
       2015-01-26 11:47:14 +08:00
    好处大致就是能省了给很多函数起名字 还有区分 post 和 get什么的
    happywowwow
        2
    happywowwow  
       2015-01-26 11:52:32 +08:00
    如果模型简单,需求简单还是可以用用吧? ——个人拙见
    之前也学了一阵,设计个博客,也觉得cbv好高大上,讲了这么多,但后面自己写着写着,发现还不如不用,强迫自己的逻辑套到cbv里太麻烦了
    icecream187
        3
    icecream187  
    OP
       2015-01-26 11:54:30 +08:00
    @happywowwow 复杂逻辑的页面就不适合用cbv了吗》?
    happywowwow
        4
    happywowwow  
       2015-01-26 11:58:24 +08:00
    @icecream187 不敢妄下断言
    只能说,我边学边写的时候,越来越觉得cbv用起来累,不断地要重写父类里的函数
    另外,cbv代码其实挺简单的,看完自己写一套自己适用的也不难吧
    geeklian
        5
    geeklian  
       2015-01-26 12:07:35 +08:00 via iPhone   ❤️ 1
    完全是习惯问题吧,但习惯了就停不下来了啊。

    主要是继承省事啊

    我习惯django自带View》项目的BaaeView》应用的AppView》页面的PageView逐级继承。

    共通的内容都少些点,PageView里逻辑代码占的比例更大。

    这是我项目常用的BaseView,鄙人不是职业程序员,写点东西就是为了方便自己工作。

    https://github.com/geeklian/CGB-BFSS/blob/master/public/views.py
    tini9
        6
    tini9  
       2015-01-26 12:16:36 +08:00
    面向对象
    函数式编程
    restful
    single page
    nosql
    TDD
    工厂模式
    元编程
    nosql
    。。。。。。。

    还有多少被程序员当作圣旨给用到死胡同的技术?
    tini9
        7
    tini9  
       2015-01-26 12:19:38 +08:00
    刚学Python的时候,不用装饰器都不好意思给人打招呼
    刚学ruby的时候,不用元编程都不好意思给人打招呼
    刚学django的时候,入过signal的坑,最后发现费这事干嘛,用函数调用不就行了吗。
    rcmerci
        8
    rcmerci  
       2015-01-26 12:24:26 +08:00
    写个好的父类会省很多事
    adieu
        9
    adieu  
       2015-01-26 12:33:12 +08:00   ❤️ 2
    最大的区别是function based view整个view的逻辑被包在了一整个function里面,要实现view的复用,只能定义很多的参数,然后在view当中用参数判断来执行不同的逻辑。当参数多了,整个view就会变得非常巨大以及难以维护。

    而class based view则将整个view的逻辑拆成了class下的多个函数,依靠函数调用来实现完整的逻辑。复用的时候要修改某一部分的逻辑就只需要重载特定的函数就可以了,可以写出复用性更好的view,同时项目当中也可以根据要求实现重载,更加灵活。

    当然class based view也不是万能的,当继承关系很复杂,代码又不是特别规整的时候,要去找某一个函数到底是被哪一个parent重载也是一个麻烦事。这个时候就会怀念全部写在一起的function based view了。

    所以还是要理解当中的区别,在合适的时候用合适的方法,千万不要听说某个方法好,就把它奉为唯一。
    yueyoum
        10
    yueyoum  
       2015-01-26 12:44:40 +08:00   ❤️ 1
    @tini9

    虽然signal 是同步调用, 但是你还是没理解 signal

    signal 是为了 解耦


    比如用户干了某件事情, 你只要发出这个 signal 就行
    至于收到这个signal后怎么处理, 你完全不关心,


    接受这个 signal的处理逻辑也完全不关心这个信号是从哪发出来的。

    你是不是觉得 函数调用 也能达到这样的效果?
    是的,只是代码混乱而已

    经典场景: 数据展现层 和 逻辑处理层,

    数据展现层 接受用户输入, 发出信号 A
    逻辑处理层 接受其他输入或自己内部变化,发出信号B

    数据展现层监听B信号, 自己更新UI
    逻辑处理曾监听A信号, 处理输入信号


    完完全全分离, 清晰明了。 要扩展也是分分种的事情
    yueyoum
        11
    yueyoum  
       2015-01-26 12:48:42 +08:00
    @happywowwow

    说明你用错了, 你的使用场景就类似与这样:

    Person 和 Food 这两种完全不一样的东西,
    你非要写一个 基类 让 Person 和 Food 继承自那个基类

    所以你要在 Person 和 Food 里面写各自的东西, 共用的东西很少
    所以你觉得累
    tini9
        12
    tini9  
       2015-01-26 12:53:18 +08:00
    @yueyoum 逻辑信号处理,那只是理论,实际上在web后台中,只有一条线索的流水线式结构,最适合梳理业务逻辑。

    信号、监听、句柄这些理念适合传统的桌面开发,用在web上会吧简单的问题复杂化。
    yueyoum
        13
    yueyoum  
       2015-01-26 12:57:44 +08:00
    @adieu

    同意你的观点

    总之 怎么方便怎么来,Class Based View 也不一定要继承自 Django 自己的 View
    比如 这个: https://github.com/yueyoum/lockscreen-image/blob/master/project/apps/image/views.py

    自己的 Class Based View 让多个url 映射到其上, 为了仅仅是共用代码和逻辑而已

    自己的风格是 函数 和 Class Based Views 混用
    tini9
        14
    tini9  
       2015-01-26 12:57:55 +08:00
    @adieu 业务逻辑封装是万恶之源,除非是上帝,以人类渺小的智商根本无法抽象这现实世界。业务逻辑封装,往往是为了一步复用,要走上十步的弯路。老老实实的把view分开写,互不干扰,是最便捷的方案
    yueyoum
        15
    yueyoum  
       2015-01-26 12:58:47 +08:00
    @tini9

    多做点项目, 你会发现 django 的 signal 根本不够用,
    你需要 message queue
    yueyoum
        16
    yueyoum  
       2015-01-26 12:59:47 +08:00
    @tini9

    >> 刚学Python的时候,不用装饰器都不好意思给人打招呼

    那你现在 用不用 装饰器? 好不好用呢?
    tini9
        17
    tini9  
       2015-01-26 13:01:58 +08:00
    @yueyoum 框架中有提供的当然会用,但不会自己实现装饰器,没有非用装饰器实现不了的需求。
    tini9
        18
    tini9  
       2015-01-26 13:05:12 +08:00
    @yueyoum
    多做点项目, 你会发现 django 的 signal 根本不够用,
    你需要 message queue
    ============================================
    不要想当然,我已经过了追求各种概念的阶段
    yueyoum
        19
    yueyoum  
       2015-01-26 13:07:23 +08:00
    @tini9

    你说的虽然是正确的,但并不是合理的

    无意义的口水 也不必了, 多看看别人的代码, 多做几年项目
    然后再回来看自己当时的言论。
    yueyoum
        20
    yueyoum  
       2015-01-26 13:09:32 +08:00
    @tini9

    >> 不要想当然,我已经过了追求各种概念的阶段
    >> 逻辑信号处理,那只是理论,实际上在web后台中,只有一条线索的流水线式结构,最适合梳理业务逻辑。


    只有一条线索的流水线式结构?


    一个人发了一个 twitter, 他所有的 followers 都要及时看到, 并且每个follower对这个新 消息都有各自不同的操作。

    一条流水线?
    neoblackcap
        21
    neoblackcap  
       2015-01-26 13:17:15 +08:00
    @tini9 我用signal主要是在异步回调,以及model pre_save之类的内置signal方法。这些地方若是都换成函数回调,恐怕之后不好维护。
    icecream187
        22
    icecream187  
    OP
       2015-01-26 13:45:12 +08:00
    多谢各位
    adieu
        23
    adieu  
       2015-01-26 14:22:11 +08:00
    @tini9 你说的有道理,所以不能乱用封装,把所有东西都揉在一起。

    但是django以及django的第三方库解决的一个核心问题是快速开发。把各种功能封装成一个个独立的app,然后开发者只需要根据自己的需要来使用是django的开发模式。那如何解决在app当中实现业务逻辑,在项目中根据需要来设置以及重载是django作为一个框架需要解决的问题。而class based view则是解决这个问题的一个办法。

    另外 @yueyoum 提到的signal解耦也是为了app的复用,独立app是不可能知道使用它的项目环境的,也不可能主动来调用项目的代码,这个时候就需要使用signal来把各个app整合起来。
    happywowwow
        24
    happywowwow  
       2015-01-26 15:22:08 +08:00
    @yueyoum
    我是使用场景不类似于你所说的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2617 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 03:12 · PVG 11:12 · LAX 19:12 · JFK 22:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.