gpt4 book ai didi

python - 如何更新 m2m 关系的序列化器字段

转载 作者:行者123 更新时间:2023-12-01 09:22:14 32 4
gpt4 key购买 nike

我正在尝试通过在 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)

一些窗口 shell 输出

打印(验证数据)

{'name': 'bedddef', 'description': 'gdddoot', 'image': 'httpdddlo', 'ingredients': [OrderedDict([('name', 'tomatoes'), ('amount', 2)]), OrderedDict([('name', 'bread'), ('amount', 3)])]}

对于成分.items() 中的键、值:
打印(键,值)

name tomatoes
amount 2
name bread
amount 3

最近(今天)我再次重新创建了整个 api,因为我丢失了它。我尝试使用 Ingredient.objects.get_or_create() 使用为 update() 方法建议的相同代码,但出现错误。

多个对象返回于/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

最佳答案

您可以使用set m2m相关管理器的方法

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,因此为了使代码更具可读性,只需分配变量_

obj, _ = Ingredient.objects.get_or_create(**ingredient)

关于python - 如何更新 m2m 关系的序列化器字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50722714/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com