问题描述
我有两个模型:
class Foo(models.Model):
name = models.CharField(max_length=64)
class Bar(models.Model):
foo = models.ForeignKey(Foo)
name = models.CharField(max_length=64)
和那些序列化器
class FooSerializer(serializers.ModelSerializer):
class Meta:
model = Foo
fields = ('pk', 'name')
class BarSerializer(serializers.ModelSerializer):
foo = ???
class Meta:
model = Bar
fields = ('pk', 'foo', 'name')
我需要为Bar
对象/bar/create
一个api /bar/create
,例如:
-
我只在输入json中提供
Foo
主键 -
我用
FooSerializer
序列化的foo
检索Bar
对象。
因此,让我们考虑一下我在数据库中有这个Foo(pk=1, name='foo')
对象,我想这样做:
-
请求:
- 开机自检/ bar /创建
-
content =
{'foo': 1, 'name': 'bar'}
-
响应
-
{'foo': {'pk': 1, 'name': 'foo'}, 'name': 'bar'}
-
我怎么能简单地做到这一点? 这样做是一种好习惯吗?
1楼
一种方法是将字段化为嵌套对象,并使别名化的嵌套对象为只读:
class BarSerializer(serializers.ModelSerializer):
foo_obj = FooSerializer(required=False,read_only=True)
class Meta:
model = Bar
fields = ('pk', 'foo', 'foo_obj', 'name')
如果存在foo
,则将其放置在Bar
的foo_obj
字段中。
在客户端,您必须使foo
和foo_obj
保持同步”,这确实很臭。
2楼
- 如何做到:一种实现方法是使用2个序列化器,您将根据请求类型进行选择:
class BarSerializer(serializers.ModelSerializer):
class Meta:
model = Bar
fields = ('pk', 'foo', 'name')
class BarNestedSerializer(BarSerializer):
class Meta(BarSerializer.Meta):
depth = 2
class BarView(generics.ListCreateAPIView):
queryset = Bar.objects.all()
def get_serializer_class(self):
return BarNestedSerializer if self.action == 'list' else BarSerializer
- 应该如何完成:为Foo对象设置一条单独的路由,您将在前端缓存该路由,并根据ID显示其查找值。 归根结底,这实际上取决于您的用例,但是通常只有在绝对必要的情况下,才应该能够避免嵌套。