V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
phithon
V2EX  ›  Django

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

  •  
  •   phithon ·
    phith0n · 2017-03-06 15:25:24 +08:00 · 4021 次点击
    这是一个创建于 2600 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

    view 尽量简单吧(虽然 最早写的 Django 里 view 写的很复杂
    zonghua
        10
    zonghua  
       2017-03-06 18:53:53 +08:00
    @phithon 另外一个 manager
    glasslion
        11
    glasslion  
       2017-03-07 22:12:53 +08:00
    Fat model. thin view, stupid serializer
    phithon
        12
    phithon  
    OP
       2017-03-07 22:42:13 +08:00
    按照你们的意见,细化了一下。
    所有 validate 有关的全放 serializer ,所有业务都写成方法放 model 里,然后 view 和信号里调用这些方法。
    @pixstone
    @glasslion
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1931 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 16:19 · PVG 00:19 · LAX 09:19 · JFK 12:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.