Django Rest Framework 可写嵌套序列化器 [英] Django Rest Framework writable nested serializers

查看:41
本文介绍了Django Rest Framework 可写嵌套序列化器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个食谱组织者作为一个班级的示例项目.除了使用一些非常基本的功能之外,我对 DRF 的经验不是很丰富.这是目标:

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:

创建具有相关成分的新配方.在创建 Recipe 对象的同时创建 Ingredient 对象.

Create a new Recipe with associated Ingredients. Create the Ingredient objects at the same time as creating the Recipe object.

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

这成功地在数据库中创建了配方对象和成分对象,但没有将成分列表与配方相关联.我认为这是因为当我运行 ingredients_data =validated_data.pop('ingredients') 时,validated_data 字典删除了它的成分,所以当我使用 validated_data,没有相关的成分.

This successfully creates the Recipe object AND the Ingredients objects in the database, but doesn't associate the list of Ingredients with the Recipe. I assume this is because when I run ingredients_data = validated_data.pop('ingredients'), the validated_data dictionary gets its Ingredients removed, so when I create a new Recipe using validated_data, there aren't associated ingredients.

但是我似乎无法找到一种方法来保持与食谱相关的成分.

However I can't seem to figure out a way to keep ingredients associated with the recipe.

推荐答案

我发现在创建所有未创建的对象之前无法建立多对多关系.(请参阅 Django 文档多对多关系页面.)

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.)

这是工作代码:

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 了,所以请持保留态度:

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

这篇关于Django Rest Framework 可写嵌套序列化器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆