[DRF]在单独的资源上使用嵌套序列化程序有什么好处?
[DRF]What are the benefits of using nested Serializers over separate resources?
plz 有人让我知道嵌套序列化器在使用非分离 apis 时有什么好处(换句话说,一个 api 和没有分离的资源一样)?
仅供参考,我正在尝试为创建和更新方法制作 3 个嵌套序列化程序。
很多地方省略了,我的图如下。
# models.py
class Foo(Model):
title = CharField(...)
class Bar(Model):
foo = ForeignKey("Foo", ...)
class Bar2(Model):
bar = ForeignKey("Bar", ...)
# serializers.py
class Bar2WriteSerializer(ModelSerializer):
def create(self, validated_date):
...
def update(self, instance, validated_date):
...
class BarWriteSerializer(ModelSerializer):
bar2 = ListField(
child=Bar2WriteSerializer(),
...
)
def create(self, validated_date):
...
bar2_serializer = self.fields["bar2"].child
bar2_serializer.create(self, validated_data):
...
def update(self, instance, validated_date):
...
bar2_serializer = self.fields["bar2"].child
bar2_serializer.update(self, instance, validated_data):
...
class FooWriteSerializer(ModelSerializer):
bar = ListField(
child=BarWriteSerializer(),
...
)
def create(self, validated_date):
...
bar_serializer = self.fields["bar"].child
bar_serializer.create(self, validated_data):
...
def update(self, instance, validated_date):
...
bar_serializer = self.fields["bar"].child
bar_serializer.update(self, instance, validated_data):
...
---已编辑---
# views.py
class FooCreateAPIView(CreateAPIView):
...
def post(self, *args, **kwargs):
return super().post(*args, **kwargs)
一般来说,当我想要一个模型 B 始终与模型 A 一起读取(或创建)的接口时,我会使用嵌套序列化器。这方面的一个例子是 Pizza
模型和 many-to-many 与 Topping
.
的关系
您希望将它们分成两个模型以实现规范化的数据库模型,但是检索比萨饼的信息而不包含其配料是没有意义的。
一个 'create' 示例可能是 UserCredentials
和 Profile
。出于安全原因,您可能希望将它们分开,但在没有附加的 Profile
.
的情况下创建 UserCredentials
是没有意义的
这里的优点是界面不太复杂。在 client-side 上,您不需要进行复杂的链式请求。 (检索披萨,然后每次检索浇头。)它还减少了服务器的开销,因为只有一个请求。
虽然有一些缺点。我倾向于避开嵌套序列化程序,因为:
- 如果您还希望能够分别 retrieve/create 这些关系,则需要两个序列化器或一个更复杂的序列化器。这需要大量维护才能使一切正常工作。
- 您最终可能会遇到多层嵌套的序列化程序,这使得将您的 API 分成明确定义的资源变得更加困难。
- 性能更难控制,因为您不能对嵌套资源应用分页。
plz 有人让我知道嵌套序列化器在使用非分离 apis 时有什么好处(换句话说,一个 api 和没有分离的资源一样)?
仅供参考,我正在尝试为创建和更新方法制作 3 个嵌套序列化程序。 很多地方省略了,我的图如下。
# models.py
class Foo(Model):
title = CharField(...)
class Bar(Model):
foo = ForeignKey("Foo", ...)
class Bar2(Model):
bar = ForeignKey("Bar", ...)
# serializers.py
class Bar2WriteSerializer(ModelSerializer):
def create(self, validated_date):
...
def update(self, instance, validated_date):
...
class BarWriteSerializer(ModelSerializer):
bar2 = ListField(
child=Bar2WriteSerializer(),
...
)
def create(self, validated_date):
...
bar2_serializer = self.fields["bar2"].child
bar2_serializer.create(self, validated_data):
...
def update(self, instance, validated_date):
...
bar2_serializer = self.fields["bar2"].child
bar2_serializer.update(self, instance, validated_data):
...
class FooWriteSerializer(ModelSerializer):
bar = ListField(
child=BarWriteSerializer(),
...
)
def create(self, validated_date):
...
bar_serializer = self.fields["bar"].child
bar_serializer.create(self, validated_data):
...
def update(self, instance, validated_date):
...
bar_serializer = self.fields["bar"].child
bar_serializer.update(self, instance, validated_data):
...
---已编辑---
# views.py
class FooCreateAPIView(CreateAPIView):
...
def post(self, *args, **kwargs):
return super().post(*args, **kwargs)
一般来说,当我想要一个模型 B 始终与模型 A 一起读取(或创建)的接口时,我会使用嵌套序列化器。这方面的一个例子是 Pizza
模型和 many-to-many 与 Topping
.
您希望将它们分成两个模型以实现规范化的数据库模型,但是检索比萨饼的信息而不包含其配料是没有意义的。
一个 'create' 示例可能是 UserCredentials
和 Profile
。出于安全原因,您可能希望将它们分开,但在没有附加的 Profile
.
UserCredentials
是没有意义的
这里的优点是界面不太复杂。在 client-side 上,您不需要进行复杂的链式请求。 (检索披萨,然后每次检索浇头。)它还减少了服务器的开销,因为只有一个请求。
虽然有一些缺点。我倾向于避开嵌套序列化程序,因为:
- 如果您还希望能够分别 retrieve/create 这些关系,则需要两个序列化器或一个更复杂的序列化器。这需要大量维护才能使一切正常工作。
- 您最终可能会遇到多层嵌套的序列化程序,这使得将您的 API 分成明确定义的资源变得更加困难。
- 性能更难控制,因为您不能对嵌套资源应用分页。