我目前正在为我的应用RESTful API实施djangorestframework。在使用它之后,我仍然不清楚.create(self, validated_data)
和.update(self, validated_data)
在序列化程序中使用了什么。据我了解, CRUD 仅调用viewsets.ModelViewSet
中的4种主要方法:create()
,retrive()
,update()
和destroy()
。
我还尝试过调试和打印内容,以了解.create()
和.update()
中何时调用ModelViewSet
和ModelSerializer
方法。显然,当我执行HTTP动词时,只调用ModelViewSet
中的方法。但是,对于ModelSerializer
,我在这两种方法中看不到任何调用。我只是想知道ModelSerializer
中使用的那些方法是什么,因为我发现人们在序列化器中大量重写这些方法。
谢谢:)
答案 0 :(得分:59)
你真的必须在视图和序列化器之间拆分。
Serializer
是一个独立的对象。它用于将Django模型(或任何类型的python数据结构,实际上)转换为序列化形式,反之亦然。
您可以随意使用它。只要您的输出中不需要URI,它甚至不需要实际的HTTP请求。
ModelSerializer
子类是一种特殊类型的Serializer
,它添加了“从模型加载”和“保存到模型”功能。
“保存到模型”入口点是save()
方法。为了更容易覆盖,它的默认实现会将其工作委托给序列化程序的create()
或update()
方法,具体取决于它是创建新模型实例还是更新模型实例。
这样做的目的是自定义:它为开发人员提供了仅覆盖create方法,更新方法或常见行为的选项。 例如,它允许您执行此类操作:
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
字段,无论是创建还是更新。
作为旁注,您可能不想这样做。设置“last_changed”字段的内容应该在视图中,而不是在序列化器中。
在完全不同的地方,Django REST框架提供Viewsets
。这些是有组织的视图集合,围绕为模型实现CRUD API。
因此,它将功能结构化为一组方法,即create()
,retrieve()
/ list()
,update()
和delete()
。
主要观点是:视图集的create()
方法与序列化程序的create()
方法之间没有任何关联。
恰好,viewset方法的默认实现使用ModelSerializer
,并且该序列化程序的save()
方法的默认实现将作业委托给具有相同名称的方法。
顺便说一下,关于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())
这在功能上等同于上面的例子,但它存在于视图集中。
回到你的问题,你应该覆盖的具体事情取决于哪个对象负责你想要添加的任务。
Serializer
的方法。Viewset
的方法。作为提示,您可能会问自己以下问题:如果我在另一个地方使用相同的序列化程序(可能是另一个视图集),它是否应该始终显示该行为?
答案 1 :(得分:14)
我终于了解.create()
和.update()
如何在Serializer
中工作(特别是ModelSerializer
)以及它们如何与Viewsets
相关联(尤其是{{1} }})。如果有人提出这个问题,我只想更清楚地澄清这个概念。
基本上,ModelViewSet
中的4种方法 CRUD :ModelViewSet
,.create()
,.retrieve()
和.update()
将处理来自HTTP动词的调用。默认情况下,ModelViewSet中的.destroy()
和.create()
将通过调用BaseSerializer类中的.update()
方法从ModelSerializer调用.create()
和.update()
。
然后,save()方法将通过确定对象.save()
是否存在来确定它是否会在ModelSerializer中调用.create()
或.update()
。
答案 2 :(得分:3)