我试图通过在SerializerClass上实现update()方法来更新提交的数据。但是,我不知道如何访问当前实例的当前成分,也不知道如何遍历验证数据,以便我可以正确分配键和值。任何建议将不胜感激!
我的序列化工具
class RecipeSerializer(ModelSerializer):
ingredients = IngredientSerializer(many=True)
owner = ReadOnlyField(source='owner.username')
class Meta:
fields = ['owner', 'name', 'description', 'image', 'ingredients']
model = Recipe
def create(self, validated_data):
ingredient_datas = validated_data.pop('ingredients')
recipe = Recipe.objects.create(**validated_data)
for ingredient_data in ingredient_datas:
recipe.ingredients.create(**ingredient_data)
return recipe
def update(self, instance, validated_data):
instance.name = validated_data.get('name', instance.name)
instance.description = validated_data.get('description', instance.description)
instance.image = validated_data.get('image', instance.image)
for ingredient in validated_data.get('ingredients'):
for key, value in ingredient.items():
print(key, value)
instance.ingredient.name = value
instance.ingredient.amount = value
instance.save()
return instance
我的模特
class Recipe(models.Model):
owner = models.ForeignKey('auth.User', related_name='recipes', on_delete=models.CASCADE)
name = models.CharField(max_length=100)
description = models.TextField(max_length=200, blank=True)
image = models.CharField(max_length=100, blank=True)
ingredients = models.ManyToManyField(Ingredient, related_name='recipes')
class Ingredient(models.Model):
name = models.CharField(max_length=50)
amount = models.IntegerField(default=1)
一些窗口外壳输出
打印(validated_data)
{'name': 'bedddef', 'description': 'gdddoot', 'image': 'httpdddlo', 'ingredients': [OrderedDict([('name', 'tomatoes'), ('amount', 2)]), OrderedDict([('name', 'bread'), ('amount', 3)])]}
for key,value.items()中的值:
打印(键,值)
name tomatoes
amount 2
name bread
amount 3
最近(今天) 我重新创建了整个api,因为我失去了它。我尝试使用相同的代码熊建议使用Ingredient.objects.get_or_create()的update()方法,但我得到一个错误说。
MultipleObjectsReturned at / api / recipes / 3 / get()返回多个成分 - 它返回2!
由于错误我替换get_or_create()只是create()会是一个糟糕的解决方案吗?
def update(self, instance, validated_data):
instance.name = validated_data.get('name', instance.name)
instance.descriptions = validated_data.get('descriptions', instance.descriptions)
instance.image = validated_data.get('image', instance.image)
ingredients = []
for ingredient in validated_data.get('ingredients'):
obj = Ingredient.objects.create(**ingredient)
ingredients.append(obj)
print(ingredients)
instance.ingredients.set(ingredients)
instance.save()
return instance
答案 0 :(得分:1)
您可以使用m2m RelatedManager的set
方法
def update(self, instance, validated_data):
instance.name = validated_data.get('name', instance.name)
instance.description = validated_data.get('description', instance.description)
instance.image = validated_data.get('image', instance.image)
ingredients = []
for ingredient in validated_data.get('ingredients'):
obj, _ = Ingredient.objects.get_or_create(**ingredient)
ingredients.append(obj)
instance.ingredients.set(ingredients)
# ^^^^^^
instance.save()
return instance
详细信息:模型实例的get_or_create
返回元组和bool值是创建新实例的,但我们不需要bool,所以为了使代码更具可读性,只需赋值变量{{ 1}}
_