Python Django rest框架:具有嵌套表示的PrimaryKeyRelatedField的行为
我有一个用django rest框架构建的API。 代码如下: 型号.pyPython Django rest框架:具有嵌套表示的PrimaryKeyRelatedField的行为,python,django,django-rest-framework,Python,Django,Django Rest Framework,我有一个用django rest框架构建的API。 代码如下: 型号.py class Ingredient(models.Model): barcode = models.CharField(max_length=13, primary_key=True) name = models.CharField(max_length=255) image = models.CharField(max_length=255) class Recipe(models.Model)
class Ingredient(models.Model):
barcode = models.CharField(max_length=13, primary_key=True)
name = models.CharField(max_length=255)
image = models.CharField(max_length=255)
class Recipe(models.Model):
name = models.CharField(max_length=255)
favorite = models.BooleanField()
owner = models.ForeignKey(
'auth.User', related_name="recipes", on_delete=models.CASCADE)
class Component(models.Model):
ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
recipe = models.ForeignKey( Recipe, related_name='components', on_delete=models.CASCADE)
quantity = models.FloatField()
class IngredientSerializer(serializers.ModelSerializer):
name = serializers.CharField(read_only=True)
image = serializers.CharField(read_only=True)
class Meta:
model = Ingredient
fields = '__all__'
class ComponentSerializer(serializers.ModelSerializer):
ingredient = serializers.PrimaryKeyRelatedField(queryset=Ingredient.objects.all())
# ingredient = IngredientSerializer()
class Meta:
model = Component
fields='__all__'
class RecipeSerializer(serializers.ModelSerializer):
components = ComponentSerializer(many=True)
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model = Recipe
fields = '__all__'
序列化程序.py
class Ingredient(models.Model):
barcode = models.CharField(max_length=13, primary_key=True)
name = models.CharField(max_length=255)
image = models.CharField(max_length=255)
class Recipe(models.Model):
name = models.CharField(max_length=255)
favorite = models.BooleanField()
owner = models.ForeignKey(
'auth.User', related_name="recipes", on_delete=models.CASCADE)
class Component(models.Model):
ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
recipe = models.ForeignKey( Recipe, related_name='components', on_delete=models.CASCADE)
quantity = models.FloatField()
class IngredientSerializer(serializers.ModelSerializer):
name = serializers.CharField(read_only=True)
image = serializers.CharField(read_only=True)
class Meta:
model = Ingredient
fields = '__all__'
class ComponentSerializer(serializers.ModelSerializer):
ingredient = serializers.PrimaryKeyRelatedField(queryset=Ingredient.objects.all())
# ingredient = IngredientSerializer()
class Meta:
model = Component
fields='__all__'
class RecipeSerializer(serializers.ModelSerializer):
components = ComponentSerializer(many=True)
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model = Recipe
fields = '__all__'
代码处于这种状态时,我可以通过选择现有配料、现有配方并输入数量来创建新的成分。但是,组件的序列化不是嵌套的:
{
"id": 8,
"quantity": 123.0,
"ingredient": "3218930313023"
},
当我在ComponentSerializer类中将代码更改为component=IngredientSerializer()
时,表示将按预期嵌套:
{
"id": 9,
"ingredient": {
"barcode": "3218930313023",
"name": "Crêpes L'Authentique",
"image": "https://static.openfoodfacts.org/images/products/321/893/031/3023/front_fr.16.400.jpg",
},
"quantity": 123.0
}
但是,当我尝试添加具有现有配方和现有成分的成分时,我得到一个错误400,并显示以下消息:
{
"ingredient": {
"barcode": [
"ingredient with this barcode already exists."
]
}
}
要获得与第一个代码相同的添加组件的行为,但使用嵌套表示(如第二个代码)的最佳方法是什么
非常感谢您的帮助。您正在使用条形码作为主键,这意味着它必须是唯一的,所以这就是您出现此错误的原因。但是我的条形码对于每种成分都是唯一的。是否可以实现这样一个事实,即如果带有条形码的成分已经存在,它将返回该成分,而不是尝试创建它?是的,您可以在视图中检查它是否已经存在,然后返回它,否则继续原始流。谢谢,我将尝试!