序列化与 '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 世界中。
例如,rec
是Recipe
模型的实例对象。
求出两个语句的区别。
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')
我正在尝试使 Django Rest Framework return 成为一个使用 through
关键字构建的对多关系。但是,我遇到了一个错误并且不知道出了什么问题。
我得到的错误是:
Got AttributeError when attempting to get a value for field
step_number
on serializerStepInfoSerializer
. The serializer field might be named incorrectly and not match any attribute or key on theStep
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 世界中。
例如,rec
是Recipe
模型的实例对象。
求出两个语句的区别。
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')