我需要序列化自引用层次结构
class Systm(models.Model):
...
parent = models.ForeignKey('self', on_delete=models.CASCADE, blank = True, null = True, related_name="children")
我能够通过以下代码实现这一目标:
class RecursiveField(serializers.Serializer):
def to_representation(self, value):
serializer = self.parent.parent.__class__(value, context=self.context)
return serializer.data
class SystmSerializer(serializers.ModelSerializer):
children = RecursiveField(many = True, read_only = True)
class Meta:
model = models.Systm
fields = ('id', 'name', 'type', 'children')
它的工作原理和一切都很明亮,除了我所做的只是复制和粘贴代码,但不知道它是如何工作的以及它的工作原理。这很烦人,我想了解它
我把' print
'命令进入' to_representation(...)
'但仍不清楚。我了解到,当self.parent.parent.__class__(value, context=self.context)
' if (image != nil)
{
....
}
else{
...
}
'已执行但不确定原因。
如果有人能向我解释,我真的很感激。
谢谢,
诉
答案 0 :(得分:0)
这基本上可以通过获取顶级序列化程序类并实例化它来返回子项的序列化值。序列化程序(或字段)的parent
属性是将其声明为字段的序列化程序实例。
self.parent
是在声明many=True
时隐式创建的List Serializer(请参阅ListSerializer)。
self.parent.parent
是SystmSerializer
个实例。
我的猜测是这个代码只有用,因为递归字段已用many=True
声明。如果您有child = RecursiveField(read_only = True)
,则代码为:
class RecursiveField(serializers.Serializer):
def to_representation(self, value):
serializer = self.parent.__class__(value, context=self.context)
return serializer.data
为简单起见,当您(或DRF)调用serialializer_instance.data
时,它会调用to_representation
来序列化对象实例。
递归在SystmSerializer.to_representation
:
to_representation(instance)
时,会在每个字段上调用to_representation(field_instance)
。recursiveField
,更确切地说是与recursiveField
相关联的ListSerializer to_representation
会为{1}}的所有孩子(如果有)致电。{/ li>
recursiveField.to_representation(child)
的实现会在子recursiveField.to_representation
对象上实例化一个新SystmSerializer
实例,然后调用Systm
,它本身会触发{{1}调用...然后您回到第1步,在SystmSerializer.data
个子对象上添加了一个新的to_representation
实例。当没有孩子时,递归结束。当然,如果孩子引用了祖先,你可能会遇到无休止的递归。