55👍
I figured out that ManyToMany relationships can’t be established until all of the uncreated objects have been created. (See the Django Docs page on many-to-many relationships.)
Here’s the working code:
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
UPDATE:
Per request of @StevePiercy, below is my update()
code. However, I haven’t looked at this in years and have no idea whatsoever if it is correct or good. I haven’t been working in Python or Django for some time now, so take this with a grain of salt:
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
14👍
Below is a helpful example for this question.
Change that part of code like this:
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
And this is the method to edit, cause an error when you want to edit.
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
Here is a link with an example. This code is similar to another answer, but if you want to try the code without any problems, you can use this repo. Good luck!
DRF Nested serializers
- [Django]-Django: Does prefetch_related() follow reverse relationship lookup?
- [Django]-Why is using thread locals in Django bad?
- [Django]-Add a custom button to a Django application's admin page