Reputation: 63
I have a Recipe and Ingredient class where i have a m2m placed on the ingredient model. I tested out the model in the admin panel and was working fine. However when i tried creating them in the shell i got an error(see the error below).
class Ingredient(models.Model):
name = models.CharField(max_length=50)
amount = models.IntegerField(default=1)
ingredients = models.ManyToManyField(Recipe, related_name='ingredients')
class IngredientSerializer(ModelSerializer):
class Meta:
fields = ['name', 'amount']
model = Ingredient
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)
class RecipeSerializer(ModelSerializer):
ingredients = IngredientSerializer(many=True)
owner = ReadOnlyField(source='owner.username')
class Meta:
fields = ['owner', 'name', 'description', 'image', 'ingredients']
model = Recipe
Shell Command
beefsoup = Recipe.objects.create(owner=user, name="beef", description="goot", image="httplo")
tomatoes = Ingredient.objects.create(ingredients=beefsoup ,name='tomatoes', amount=2)
Error
TypeError: Direct assignment to the forward side of a many-to-many set is prohibited. Use ingredients.set() instead.
Upvotes: 4
Views: 4522
Reputation: 594
As the error message and Django Docs suggest, your snippet should look this way:
beefsoup = Recipe.objects.create(owner=user, name="beef", description="goot", image="httplo")
beefsoup.ingredients.create(name='tomatoes', amount=2)
Besides that, judging by model & property names, it seems that your relationship design is incorrect. It should rather look this way:
class Ingredient(models.Model):
name = models.CharField(max_length=50)
amount = models.IntegerField(default=1)
class IngredientSerializer(ModelSerializer):
class Meta:
fields = ['name', 'amount']
model = Ingredient
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(Ingredients, related_name='recipes')
class RecipeSerializer(ModelSerializer):
ingredients = IngredientSerializer(many=True)
owner = ReadOnlyField(source='owner.username')
class Meta:
fields = ['owner', 'name', 'description', 'image', 'ingredients']
model = Recipe
Note that ingredients
now reside in Recipe
model.
Upvotes: 4