序列化与 'through' table 的关系时出现 AttributeError

AttributeError when serializing relationship with 'through' table

我正在尝试使 Django Rest Framework return 成为一个使用 through 关键字构建的对多关系。但是,我遇到了一个错误并且不知道出了什么问题。

我得到的错误是:

Got AttributeError when attempting to get a value for field step_number on serializer StepInfoSerializer. The serializer field might be named incorrectly and not match any attribute or key on the Step instance. Original exception text was: 'Step' object has no attribute 'step_number'.

这是我的模型:

class Step(BaseModel):

    description = models.TextField(null=False, blank=False)

class StepInfo(BaseModel):

    recipe = models.ForeignKey('Recipe')
    step = models.ForeignKey(Step)
    step_number = models.IntegerField()

class Recipe(BaseModel):

    title = models.CharField(max_length=100)
    steps = models.ManyToManyField(Step, through='StepInfo')

以及序列化器的实现:

class StepInfoSerializer(serializers.HyperlinkedModelSerializer):

    description = serializers.CharField(source="step.description")

    class Meta:
        model = StepInfo
        fields = ('id',
                  'step_number',
                  'description')


class RecipeSerializer(serializers.HyperlinkedModelSerializer):

    steps = StepInfoSerializer(many=True, read_only=True)

    class Meta:
        model = Recipe
        fields = ('id',
                  'steps')

任何人都可以解释一下这个问题吗?我真的很感激! 谢谢!

最简单的更改方法是更改​​ RecipeSerializer

中步骤的来源
class RecipeSerializer(serializers.HyperlinkedModelSerializer):

    steps = StepInfoSerializer(many=True, read_only=True, source='stepinfo_set')

现在我来解释一下。

首先,仅在 Django 世界中。

例如,recRecipe模型的实例对象。

求出两个语句的区别。

rec.steps.all()
rec.stepinfo_set.all()

rec.steps.all() 将 return 是一个 Step 对象实例数组,确保它是 ManyToManyField 的 目标模型,而不是 通过模型。

如果要访问through模型,需要从related_name访问ForeignKey在Through Model中引用当前模型( StepInfo 模型)。

稍后,我将添加一个带有 related_name 的示例。

由于在你的StepInfo中没有指定related_name,所以django会自动给你一个默认的related_namestepinfo_set。 (这个名字就是第一个片段中的名字)。

所以 return 将回到如何通过实例。只是 rec.setpinfo_set.all().

好的,最后,我建议您将 related_name 添加到您的 Through Models 中的 ForeignKey。

class StepInfo(BaseModel):

    recipe = models.ForeignKey('Recipe', related_name='stepinfos')
    step = models.ForeignKey(Step, related_name='stepinfos')
    step_number = models.IntegerField()

class RecipeSerializer(serializers.HyperlinkedModelSerializer):

    steps = StepInfoSerializer(many=True, read_only=True, source='stepinfos')