什么时候在 django rest 框架序列化程序中调用创建和更新?
When are create and update called in djangorestframework serializer?
我目前正在为我的应用实施 djangorestframework RESTful API。玩弄了之后,我还是不太清楚 .create(self, validated_data)
和 .update(self, validated_data)
在序列化器中的用途。据我了解,CRUD只调用了viewsets.ModelViewSet
中的4个主要方法:create()
、retrive()
、update()
和destroy()
.
我也已经尝试调试并打印出一些东西,以查看 .create()
和 .update()
方法何时在 ModelViewSet
和 ModelSerializer
中被调用。显然,当我执行 HTTP 动词时,只有 ModelViewSet
中的方法被调用。但是,对于 ModelSerializer
,我没有看到这 2 个方法有任何调用。我只想知道 ModelSerializer
中使用的那些方法是什么,因为我看到人们在序列化程序中大量重写这些方法。
其余-api设计创建、读取、更新和删除是一个标准。
create 和 update 区别不大。
请参考this和
参见 create() 方法将创建一个项目。
和
update()方法需要指定要更新的项目。
我终于明白 .create()
和 .update()
在 Serializer
中是如何工作的(尤其是 ModelSerializer
)以及它们是如何连接到 Viewsets
(尤其是 ModelViewSet
).如果有人提出这个问题,我只是想更清楚地阐明这个概念。
基本上,CRUD ModelViewSet
中的 4 种方法:.create()
、.retrieve()
、.update()
和 .destroy()
将处理来自 HTTP 动词的调用。默认情况下,ModelViewSet 中的 .create()
和 .update()
将通过调用 BaseSerializer class 中的 .save()
方法来调用 ModelSerializer 中的 .create()
和 .update()
.
然后save()方法会通过判断对象self.instance
是否存在来判断是调用ModelSerializer中的.create()
还是.update()
您确实必须在视图和序列化程序之间进行拆分。
序列化器
Serializer
是一个独立的对象。它用于将 Django 模型(或任何类型的 python 数据结构,实际上)转换为序列化形式,反之亦然。
您可以在任何地方使用它。只要您的输出中不需要 URI,它甚至不需要实际的 HTTP 请求。
ModelSerializer
子类是一种特殊的 Serializer
,它添加了“从模型加载”和“保存到模型”功能。
“保存到模型”入口点是 save()
方法。为了更容易覆盖,它的默认实现会将其工作委托给序列化程序的 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
字段,无论是创建还是更新。
作为旁注,您可能不想这样做。诸如设置“last_changed”字段之类的事情应该存在于视图中,而不是序列化程序中。
视图集
在一个完全不同的地方,Django REST 框架提供 Viewsets
。这些是有组织的视图集合,围绕着为模型实施 CRUD API。
因此,它将其功能结构化为一组方法,即 create()
、retrieve()
/list()
、update()
和 delete()
.
要点是:视图集的 create()
方法和序列化器的 create()
方法之间没有任何联系。
碰巧视图集方法的默认实现使用 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())
这在功能上等同于上面的示例,但存在于视图集中。
结论
所以回到你的问题,你应该覆盖的具体内容取决于哪个对象负责你要添加的任务。
- 如果您的自定义行为是序列化过程的一部分,即将原始数据转换回适当的 Django 模型并保存的过程,那么您应该覆盖
Serializer
的方法。
- 另一方面,如果您的自定义行为特定于您的视图集,那么您应该覆盖
Viewset
的方法。
作为提示,您可能会问自己以下问题:如果我在另一个地方(可能是另一个视图集)使用相同的序列化程序,它是否应该始终显示该行为?
我目前正在为我的应用实施 djangorestframework RESTful API。玩弄了之后,我还是不太清楚 .create(self, validated_data)
和 .update(self, validated_data)
在序列化器中的用途。据我了解,CRUD只调用了viewsets.ModelViewSet
中的4个主要方法:create()
、retrive()
、update()
和destroy()
.
我也已经尝试调试并打印出一些东西,以查看 .create()
和 .update()
方法何时在 ModelViewSet
和 ModelSerializer
中被调用。显然,当我执行 HTTP 动词时,只有 ModelViewSet
中的方法被调用。但是,对于 ModelSerializer
,我没有看到这 2 个方法有任何调用。我只想知道 ModelSerializer
中使用的那些方法是什么,因为我看到人们在序列化程序中大量重写这些方法。
其余-api设计创建、读取、更新和删除是一个标准。 create 和 update 区别不大。
请参考this和
参见 create() 方法将创建一个项目。
和
update()方法需要指定要更新的项目。
我终于明白 .create()
和 .update()
在 Serializer
中是如何工作的(尤其是 ModelSerializer
)以及它们是如何连接到 Viewsets
(尤其是 ModelViewSet
).如果有人提出这个问题,我只是想更清楚地阐明这个概念。
基本上,CRUD ModelViewSet
中的 4 种方法:.create()
、.retrieve()
、.update()
和 .destroy()
将处理来自 HTTP 动词的调用。默认情况下,ModelViewSet 中的 .create()
和 .update()
将通过调用 BaseSerializer class 中的 .save()
方法来调用 ModelSerializer 中的 .create()
和 .update()
.
然后save()方法会通过判断对象self.instance
是否存在来判断是调用ModelSerializer中的.create()
还是.update()
您确实必须在视图和序列化程序之间进行拆分。
序列化器
Serializer
是一个独立的对象。它用于将 Django 模型(或任何类型的 python 数据结构,实际上)转换为序列化形式,反之亦然。
您可以在任何地方使用它。只要您的输出中不需要 URI,它甚至不需要实际的 HTTP 请求。
ModelSerializer
子类是一种特殊的 Serializer
,它添加了“从模型加载”和“保存到模型”功能。
“保存到模型”入口点是 save()
方法。为了更容易覆盖,它的默认实现会将其工作委托给序列化程序的 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
字段,无论是创建还是更新。
作为旁注,您可能不想这样做。诸如设置“last_changed”字段之类的事情应该存在于视图中,而不是序列化程序中。
视图集
在一个完全不同的地方,Django REST 框架提供 Viewsets
。这些是有组织的视图集合,围绕着为模型实施 CRUD API。
因此,它将其功能结构化为一组方法,即 create()
、retrieve()
/list()
、update()
和 delete()
.
要点是:视图集的 create()
方法和序列化器的 create()
方法之间没有任何联系。
碰巧视图集方法的默认实现使用 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())
这在功能上等同于上面的示例,但存在于视图集中。
结论
所以回到你的问题,你应该覆盖的具体内容取决于哪个对象负责你要添加的任务。
- 如果您的自定义行为是序列化过程的一部分,即将原始数据转换回适当的 Django 模型并保存的过程,那么您应该覆盖
Serializer
的方法。 - 另一方面,如果您的自定义行为特定于您的视图集,那么您应该覆盖
Viewset
的方法。
作为提示,您可能会问自己以下问题:如果我在另一个地方(可能是另一个视图集)使用相同的序列化程序,它是否应该始终显示该行为?