I have the following code of my model:
class Recipe(BaseModel):
"""
Recipe model class using for contains recipe, which can be sent to chat
with coach. In text recipe contains RecipeStep.
"""
ingredients = models.ManyToManyField(
Product,
verbose_name=_("ingredients"),
related_name="ingredients"
)
portion_size = models.PositiveSmallIntegerField(
_("portion size")
)
# TODO: add "add_to_meal" logic (user can add recipe to his meal).
# it can be reached by using M2M with user and creating new relation for
# user and recipe on user click on special button.
def __str__(self) -> str:
return f"recipe \"{self.title}\""
def __repr__(self) -> str:
return f"Recipe({self.pk=}, {self.title=}, {self.is_published=})"
class Meta:
verbose_name = _("recipe")
verbose_name_plural = _("recipes")
BaseModel
is abstract class, that has basic structure of Article-like models (title, description, published_at, etc.).
And the following code of serializers for model:
class RecipeSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(read_only=True)
title = serializers.CharField(min_length=1, max_length=200, required=True)
ingredients = ProductSerializer(many=True, read_only=False)
portion_size = serializers.IntegerField(min_value=0, required=True)
is_published = serializers.BooleanField(required=False, default=False)
publish_date = serializers.DateField(
allow_null=True,
required=False,
read_only=True
)
image_add_id = serializers.UUIDField(required=True)
def create(self, validated_data):
validated_data.pop('image_add_id', None)
return super().create(validated_data)
class Meta:
model = Recipe
fields = "__all__"
I need to create Recipe with passing list of existing ingredient pks, and not create new ingredients like:
{
...
"ingredients": [
"d6c065a2-7f80-47f3-8c0e-186957b07269",
"4b8359d2-073a-4f41-b3cc-d8d2cfb252d5",
"b39e4cc2-18c3-4e4a-880a-6cb2ed556160",
"603e2333-0ddf-41f1-99f5-3dfe909eb969"
]
}
How should I do this?
CodePudding user response:
You are using model serializers so you don't have to redefine serializers fields. Also, since you are adding many related field you have to add after model instance created as follow
class RecipeSerializer(serializers.ModelSerializer):
class Meta:
model = Recipe
fields = '__all__'
def create(self, validated_data):
ingredients = validated_data.pop('ingredients')
instance = super().create(validated_data)
for ingredient in ingredients:
instance.ingredients.add(ingredient)
return instance