V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
phithon
5.05D
V2EX  ›  Django

restframework 你们会把逻辑放 view 还是 serializer 还是 model 里

  •  
  •   phithon ·
    phith0n · Mar 6, 2017 · 4700 views
    This topic created in 3343 days ago, the information mentioned may be changed or developed.

    restframework 你们会把额外逻辑放 view 还是 serializer 还是 model 里?

    举个例子,两个 model ,一个 product ,一个 log 。 逻辑是用户添加 product ,成功以后向 log 表添加一条日志。

    添加日志这个操作放在哪里比较好?

    class Product(models.Model):
        ...
        
        def save(self, *args, **kwargs):
            Log.objects.create(...)
            super().save(...)
    

    或者

    class ProductSerializer(serializers.ModelSerializer):
        ...
        
        def save(self, **kwargs):
            ...
            Log.objects.create(...)
    

    或者

    class ProductTrain(generics.CreateAPIView):
        serializer_class = serializers.ProductSerializer
        ...
        
        def perform_create(self, serializer):
            serializer.save(...)
            Log.objects.create(...)
    

    同样,如果用 Django 原生的 form ,也有这个问题。。。求一个好的设计模式?

    12 replies    2017-03-07 22:42:13 +08:00
    hefish
        1
    hefish  
       Mar 6, 2017
    我个人喜欢放在 model 。
    方便写自动化测试脚本
    neoblackcap
        2
    neoblackcap  
       Mar 6, 2017
    我会写一个 service 类来做业务逻辑
    phithon
        3
    phithon  
    OP
       Mar 6, 2017
    @neoblackcap 是不是有点不符合 django 的设计模式?官方没说这个东西,有木有案例我参考一下?
    Hstar
        4
    Hstar  
       Mar 6, 2017
    如果是这三选一, 我会放在 serializer 里. 因为从逻辑上讲, 这个操作是业务操作的一部分. 放在 model 里感觉不纯净, 放在 view 里感觉太分离.
    111111111111
        5
    111111111111  
       Mar 6, 2017
    你这些情况为何不试试用 post_save 信号?更 django 一些
    111111111111
        6
    111111111111  
       Mar 6, 2017
    考虑适用范围吧
    你的目的是 A.save 触发 B.create

    写在 views 里,只有这个接口的代码会这么执行
    写在 serializer 里,所有用了这个 Serializer 的地方会这么执行
    写在 model 里,任何地方调用 save 都会执行

    同时你要知道,不仅仅是创建会执行 save ,修改保存也会执行 save 方法的
    phithon
        7
    phithon  
    OP
       Mar 6, 2017
    @111111111111 有些情况还是不太适合信号,我举得这个例子可能比较蛋疼。。。
    而且不一定 B 操作是数据库,有时候是 celery 任务,有时候是 sendmail 。。反正经常会有这种困惑。
    不过修改和创建有时候确实会忘记,特别是这三者再加信号混用的时候,一大堆 save
    phithon
        8
    phithon  
    OP
       Mar 6, 2017
    @Hstar @111111111111 比较倾向 serializer
    model 肯定不行,因为 create 和 update 都放一块,还得判断一层,耦合性太高
    serializer 比较好,没什么缺点
    view 的话,记得以前学 PHP 的时候就有人建议 MVC 架构中 C 不要太大,感觉确实也不好

    但又出来一个问题,如果是原生 django 的 form ,就有个问题。
    serializer 可以从 context 中获取 request , form 好像不能获取 request ?需要手工传入。。
    这样的话,很多和用户、请求相关的操作就要额外写一堆相同的代码
    pixstone
        9
    pixstone  
       Mar 6, 2017
    model 里放 model 相关的数据交付,比如 reset_password ,disable_user 什么的。

    serializer 放数据校验检查什么的。

    view 尽量简单吧(虽然 最早写的 Django 里 view 写的很复杂
    zonghua
        10
    zonghua  
       Mar 6, 2017
    @phithon 另外一个 manager
    glasslion
        11
    glasslion  
       Mar 7, 2017
    Fat model. thin view, stupid serializer
    phithon
        12
    phithon  
    OP
       Mar 7, 2017
    按照你们的意见,细化了一下。
    所有 validate 有关的全放 serializer ,所有业务都写成方法放 model 里,然后 view 和信号里调用这些方法。
    @pixstone
    @glasslion
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   794 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 60ms · UTC 20:42 · PVG 04:42 · LAX 13:42 · JFK 16:42
    ♥ Do have faith in what you're doing.