Django 使用深度选项支持创建相同类型的嵌套序列化程序
假设模型中存在子关系和父关系,例如:Django 使用深度选项支持创建相同类型的嵌套序列化程序,django,django-rest-framework,Django,Django Rest Framework,假设模型中存在子关系和父关系,例如: class Foo(models.Model): parent = models.ForeignKey('Foo', related_name='children') 现在我想要一个序列化程序来显示Foo对象的子对象,如下所示: class FooSerializer(serializers.ModelSerializer): children = FooSerializer(many=True) class Meta: model =
class Foo(models.Model):
parent = models.ForeignKey('Foo', related_name='children')
现在我想要一个序列化程序来显示Foo
对象的子对象,如下所示:
class FooSerializer(serializers.ModelSerializer):
children = FooSerializer(many=True)
class Meta:
model = Foo
fields = '__all__'
但这给了我一个错误,它在创建类时无法识别FooSerializer
,这与python解析类的方式有关。我如何实现这种关系并使用序列化程序获取其子级。
我必须提到,我希望能够使用嵌套序列化程序的depth
选项
我使用的是django 2.2.7和rest框架3.10.1
编辑
可能有一些嵌套级别,必须使用depth
选项停止,在一些级别之后,必须将其展平,因此我希望能够沿嵌套序列化程序使用depth
选项 属性用于ForeignKey关系,在您的情况下,它是反向FK关系,因此不起作用
您可以通过使用嵌套配置中的多个序列化程序来实现类似深度的功能
示例1:结果类似于depth=1
示例2:结果类似于depth=2
关键点是,不要定义要停止嵌套效果的子项
,基于另一个,我编写了一个支持深度选项的版本:
class FooSerializer(serializers.ModelSerializer):
children = serializers.SerializerMethodField()
def get_children(self, obj):
if obj.children:
depth = getattr(self.Meta, 'depth', None)
if not depth:
depth = self.context.get('depth', 0)
if depth:
return SessionSerializer(obj.children.all(),
many=True,
context={'depth': depth - 1}).data
else:
return [child.id for child in obj.children.all()]
else:
return []
它也支持深度选项。检查此问题,也不确定它是否有效,但请尝试depth=1
参数。请参见此处的详细信息:正如您所猜测的,它不适用于深度参数为什么深度
超过嵌套序列化程序
?我的问题不完全,可能有一些嵌套关系,我希望能够在某个级别停止,因此在我的示例中使用深度是至关重要的。我尝试了它,但它不适用于depth
option不适用于depth?我不要求包括深度
我不明白你想说什么say@MohsenTamiz这个解决方案将按原样工作,我已经测试并验证了我在问题中提到的我希望能够设置序列化程序的深度选项,例如,将其设置为1意味着只显示一个级别的子级。正如@neverwalkinner在问题注释中所说,此解决方案仅在没有深度
选项时有效。深度
用于外键
关系,在您的情况下,它是反向FK关系
class FooBaseSerializerLevel2(serializers.ModelSerializer):
class Meta:
model = Foo
fields = '__all__'
class FooBaseSerializerLevel1(serializers.ModelSerializer):
children = FooBaseSerializerLevel2(many=True)
class Meta:
model = Foo
fields = '__all__'
class FooBaseSerializerLevel0(serializers.ModelSerializer):
children = FooBaseSerializerLevel1(many=True)
class Meta:
model = Foo
fields = '__all__'
class FooSerializer(serializers.ModelSerializer):
children = serializers.SerializerMethodField()
def get_children(self, obj):
if obj.children:
depth = getattr(self.Meta, 'depth', None)
if not depth:
depth = self.context.get('depth', 0)
if depth:
return SessionSerializer(obj.children.all(),
many=True,
context={'depth': depth - 1}).data
else:
return [child.id for child in obj.children.all()]
else:
return []