
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 ,也有这个问题。。。求一个好的设计模式?
1 hefish 2017 年 3 月 6 日 我个人喜欢放在 model 。 方便写自动化测试脚本 |
2 neoblackcap 2017 年 3 月 6 日 我会写一个 service 类来做业务逻辑 |
3 phithon OP @neoblackcap 是不是有点不符合 django 的设计模式?官方没说这个东西,有木有案例我参考一下? |
4 Hstar 2017 年 3 月 6 日 如果是这三选一, 我会放在 serializer 里. 因为从逻辑上讲, 这个操作是业务操作的一部分. 放在 model 里感觉不纯净, 放在 view 里感觉太分离. |
5 111111111111 2017 年 3 月 6 日 你这些情况为何不试试用 post_save 信号?更 django 一些 |
6 111111111111 2017 年 3 月 6 日 考虑适用范围吧 你的目的是 A.save 触发 B.create 写在 views 里,只有这个接口的代码会这么执行 写在 serializer 里,所有用了这个 Serializer 的地方会这么执行 写在 model 里,任何地方调用 save 都会执行 同时你要知道,不仅仅是创建会执行 save ,修改保存也会执行 save 方法的 |
7 phithon OP @111111111111 有些情况还是不太适合信号,我举得这个例子可能比较蛋疼。。。 而且不一定 B 操作是数据库,有时候是 celery 任务,有时候是 sendmail 。。反正经常会有这种困惑。 不过修改和创建有时候确实会忘记,特别是这三者再加信号混用的时候,一大堆 save |
8 phithon OP @Hstar @111111111111 比较倾向 serializer model 肯定不行,因为 create 和 update 都放一块,还得判断一层,耦合性太高 serializer 比较好,没什么缺点 view 的话,记得以前学 PHP 的时候就有人建议 MVC 架构中 C 不要太大,感觉确实也不好 但又出来一个问题,如果是原生 django 的 form ,就有个问题。 serializer 可以从 context 中获取 request , form 好像不能获取 request ?需要手工传入。。 这样的话,很多和用户、请求相关的操作就要额外写一堆相同的代码 |
9 pixstone 2017 年 3 月 6 日 model 里放 model 相关的数据交付,比如 reset_password ,disable_user 什么的。 serializer 放数据校验检查什么的。 view 尽量简单吧(虽然 最早写的 Django 里 view 写的很复杂 |
11 glasslion 2017 年 3 月 7 日 Fat model. thin view, stupid serializer |