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

2017-03-06 15:25:24 +08:00
 phithon

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 ,也有这个问题。。。求一个好的设计模式?

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

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

同时你要知道,不仅仅是创建会执行 save ,修改保存也会执行 save 方法的
phithon
2017-03-06 16:51:57 +08:00
@111111111111 有些情况还是不太适合信号,我举得这个例子可能比较蛋疼。。。
而且不一定 B 操作是数据库,有时候是 celery 任务,有时候是 sendmail 。。反正经常会有这种困惑。
不过修改和创建有时候确实会忘记,特别是这三者再加信号混用的时候,一大堆 save
phithon
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
2017-03-06 18:39:58 +08:00
model 里放 model 相关的数据交付,比如 reset_password ,disable_user 什么的。

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

view 尽量简单吧(虽然 最早写的 Django 里 view 写的很复杂
zonghua
2017-03-06 18:53:53 +08:00
@phithon 另外一个 manager
glasslion
2017-03-07 22:12:53 +08:00
Fat model. thin view, stupid serializer
phithon
2017-03-07 22:42:13 +08:00
按照你们的意见,细化了一下。
所有 validate 有关的全放 serializer ,所有业务都写成方法放 model 里,然后 view 和信号里调用这些方法。
@pixstone
@glasslion

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/345321

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX