Django Rest Framework writable nested serializers

后端 未结 2 1911
耶瑟儿~
耶瑟儿~ 2020-11-28 22:51

I\'m writing a recipe organizer as a sample project for a class. I\'m not very experienced with DRF other than using some very basic functionality. Here\'s the objective:

相关标签:
2条回答
  • 2020-11-28 23:20

    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
    
    0 讨论(0)
  • 2020-11-28 23:22

    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

    0 讨论(0)
提交回复
热议问题