クラスのサンプルプロジェクトとしてレシピオーガナイザーを書いています。いくつかの非常に基本的な機能を使用する以外は、DRFの経験はあまりありません。目的は次のとおりです。
関連する成分を含む新しいレシピを作成します。レシピオブジェクトの作成と同時に、成分オブジェクトを作成します。
models.py:
_class Ingredient(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Recipe(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(blank=True, null=True, help_text="This is a quick description of your recipe")
directions = models.TextField(help_text="How to make the recipe")
ingredients = models.ManyToManyField(Ingredient)
def __str__(self):
return self.name
_
serializers.py
_class IngredientSerializer(serializers.ModelSerializer):
class Meta:
model = Ingredient
class RecipeSerializer(serializers.ModelSerializer):
ingredients = IngredientSerializer(many=True)
class Meta:
model = Recipe
def create(self, validated_data):
ingredients_data = validated_data.pop('ingredients')
recipe = Recipe.objects.create(**validated_data)
for ingredient_data in ingredients_data:
Ingredient.objects.create(**ingredient_data)
return recipe
_
これにより、RecipeオブジェクトとIngredientsオブジェクトがデータベースに正常に作成されますが、IngredientsのリストはRecipeに関連付けられません。これは、ingredients_data = validated_data.pop('ingredients')
を実行すると_validated_data
_辞書の成分が削除されるため、_validated_data
_を使用して新しいレシピを作成すると、関連する成分がないためだと思います。
ただし、レシピに関連する材料を保持する方法を理解できないようです。
未作成のオブジェクトがすべて作成されるまで、ManyToMany関係を確立できないことがわかりました。 (Django Docs 多対多の関係のページ を参照してください。)
作業コードは次のとおりです。
serializers.py
_class RecipeSerializer(serializers.ModelSerializer):
ingredients = IngredientSerializer(many=True)
class Meta:
model = Recipe
def create(self, validated_data):
ingredients_data = validated_data.pop('ingredients')
recipe = Recipe.objects.create(**validated_data)
for ingredient in ingredients_data:
ingredient, created = Ingredient.objects.get_or_create(name=ingredient['name'])
recipe.ingredients.add(ingredient)
return recipe
_
@StevePiercyのリクエストごとに、以下は私のupdate()
コードです。 しかし、、私はこれを何年も見ていないし、それが正しいか良いかどうか全くわからない。私はPythonまたはDjangoでしばらく働いていませんでした。
_def update(self, instance, validated_data):
ingredients_data = validated_data.pop('ingredients')
instance.name = validated_data.get('name', instance.name)
instance.description = validated_data.get('description', instance.description)
instance.directions = validated_data.get('directions', instance.directions)
instance.photo = validated_data.get('photo', instance.photo)
ingredients_list = []
for ingredient in ingredients_data:
ingredient, created = Ingredient.objects.get_or_create(name=ingredient["name"])
ingredients_list.append(ingredient)
instance.ingredients = ingredients_list
instance.save()
return instance
_
これは、この質問の小さな例です。
これによりコードのその部分を変更します。
def create(self, validated_data):
ingredients_data = validated_data.pop('ingredients')
recipe = Recipe.objects.create(**validated_data)
for ingredient in ingredients_data:
ingredient, created = Ingredient.objects.get_or_create(name=ingredient['name'])
recipe.ingredients.add(ingredient)
return recipe
そして、これは編集する方法であり、編集したいときにエラーを引き起こします。
def update(self, instance, validated_data):
ingredients_data = validated_data.pop('ingredients')
instance.name = validated_data['name']
instance.description = validated_data['description']
instance.directions = validated_data['directions']
for ingredient in ingredients_data:
ingredient, created = Ingredient.objects.get_or_create(name=ingredient['name'])
recipe.ingredients.add(ingredient)
return instance
例とのリンクは、このコードは別の答えに似ていますが、コードを試してみたい場合は、ここに問題なくレポがあります。がんばろう! DRFネストされたシリアライザー