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-03-06 15:34:06 +08:00
我个人喜欢放在 model 。
方便写自动化测试脚本 |
2
neoblackcap 2017-03-06 15:42:19 +08:00
我会写一个 service 类来做业务逻辑
|
3
phithon OP @neoblackcap 是不是有点不符合 django 的设计模式?官方没说这个东西,有木有案例我参考一下?
|
4
Hstar 2017-03-06 16:24:28 +08:00
如果是这三选一, 我会放在 serializer 里. 因为从逻辑上讲, 这个操作是业务操作的一部分. 放在 model 里感觉不纯净, 放在 view 里感觉太分离.
|
5
111111111111 2017-03-06 16:25:07 +08:00
你这些情况为何不试试用 post_save 信号?更 django 一些
|
6
111111111111 2017-03-06 16:31:13 +08:00
考虑适用范围吧
你的目的是 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-03-06 18:39:58 +08:00
model 里放 model 相关的数据交付,比如 reset_password ,disable_user 什么的。
serializer 放数据校验检查什么的。 view 尽量简单吧(虽然 最早写的 Django 里 view 写的很复杂 |
11
glasslion 2017-03-07 22:12:53 +08:00
Fat model. thin view, stupid serializer
|