反向序列化多对多关系会导致递归错误

问题描述 投票:0回答:1

根据这个答案,我尝试将对象从多对多关系反向序列化。

使用序列化器方法字段,我尝试填充具有 person 类型的人员,但这会导致 django 出现

RecursionError

我可以看到这个问题,

PersonA
PersonTypeA
,谁有
PersonA
等,但我不知道如何将返回的人“扁平化”到一个级别。

如何克服递归错误?

型号:

class PersonType(models.Model):
    name = models.CharField(max_length=128)
    created = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now_add=True)
    start_time = models.DateTimeField()
    end_time = models.DateTimeField(null=True)

class Person(models.Model):
    title = models.CharField(max_length=16)
    first_name = models.CharField(max_length=128)
    last_name = models.CharField(max_length=128)
    email_address = models.CharField(max_length=256)
    created = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now_add=True)
    start_time = models.DateTimeField()
    end_time = models.DateTimeField(null=True)

    person_types = models.ManyToManyField(PersonType, related_name="people")

序列化器:

class PersonTypeSerializer(serializers.ModelSerializer):

    people = serializers.SerializerMethodField()

    class Meta:
        model = PersonType
        fields = '__all__'

    def get_people(self, obj):
        people = obj.people.all()
        response = PersonSerializer(people, many=True).data
        return response

class PersonSerializer(serializers.ModelSerializer):

    person_types = PersonTypeSerializer(many=True)

    class Meta:
        model = Person
        fields = '__all__'
        depth = 1
django django-rest-framework
1个回答
1
投票

发生

RecursionError
并不是直接因为模型,而是因为您尝试序列化数据的形式。

如果

Person
实例包含在包含该
Type
Person
中,那么您将进入一个永无休止的递归循环,其中您的
serializers
永远互相调用。

要立即解决错误,不要尝试从

SerializerMethodField
序列化 QuerySet,而是返回其值:

class PersonTypeSerializer(serializers.ModelSerializer):

    people = serializers.SerializerMethodField()

    class Meta:
        model = PersonType
        fields = '__all__'

    def get_people(self, obj):
        people = obj.people.all()
        return people.values()

class PersonSerializer(serializers.ModelSerializer):
    ...

另外,我需要指出,您正在尝试使用

depth
来表示嵌套关系。但相反,通过创建自己的序列化器(PersonTypeSerializer),您可以覆盖它,因此您可以只拥有一个序列化器并让框架为您遍历它:

class PersonSerializer(serializers.ModelSerializer):

    class Meta:
        model = Person
        fields = '__all__'
        depth = 1

尽管如此,这不会返回

people
字段,该字段是您自定义的一部分。这意味着
depth
在这种情况下是没有用的。

© www.soinside.com 2019 - 2024. All rights reserved.