您确实必须在视图和序列化程序之间进行拆分.
Serializers
Serializer
是一个独立的对象.它用于将Django模型(实际上是任何类型的python数据 struct )转换为序列化形式,反之亦然.
ModelSerializer
子类是一种特殊的Serializer
,它添加了"从模型加载"和"保存到模型"功能.
"保存到模型"入口点是save()
方法.为便于覆盖,其默认实现将其工作委托给序列化程序的create()
或update()
方法,具体取决于它是创建新的模型实例还是更新模型实例.
它的目的是定制:它为开发人员提供了只覆盖create方法、update方法或常见行为的选项.
def save(self, **kwargs):
# Will be done on every save
kwargs['last_changed'] = timezone.now()
return super().save(**kwargs)
def create(self, instance, data):
# Will only be done if a new object is being created
data['initial_creation'] = timezone.now()
return super().create(instance, data)
这是一个基本的例子.在那里,每次保存对象(无论是创建还是更新)时都会设置last_changed
字段.
Viewsets
在一个完全不同的地方,Django 睡觉框架提供了Viewsets
个.这些是有组织的视图集合,围绕实现模型的CRUD API.
因此,它将其功能 struct 化为一组方法,即create()
、retrieve()
/list()
、update()
和delete()
.
要点是:there is no connection whatsoever between the viewset's 100 method and the serializer's 100 method.
恰好视图集的方法的默认实现使用ModelSerializer
,并且该序列化程序的save()
方法的默认实现将作业(job)委托给同名的方法.
顺便说一句,关于last_changed
个例子,下面是您在视图中的操作方式:
def perform_create(self, serializer):
now = timezone.now()
serializer.save(initial_creation=now, last_changed=now)
def perform_update(self, serializer):
serializer.save(last_changed=timezone.now())
这在功能上与上面的示例相同,但存在于视图集中.
Conclusion
回到您的问题,您应该覆盖的具体内容取决于您要添加的任务由哪个对象负责.
- 如果您的自定义行为是序列化过程的一部分,即将原始数据转换回适当的Django模型并将其保存的过程,那么您应该覆盖
Serializer
的方法.
- 另一方面,如果您的自定义行为特定于您的视集,则应替代
Viewset
的方法.
作为提示,您可能会问自己以下问题:如果我在另一个地方(可能是另一个视图集)使用相同的序列化程序,它是否应该始终显示该行为?