簡體   English   中英

Django Rest Framework 可寫嵌套序列化程序

[英]Django Rest Framework writable nested serializers

我正在編寫一個食譜組織者作為一個班級的示例項目。 除了使用一些非常基本的功能之外,我對 DRF 的經驗並不多。 這是目標:

使用相關成分創建新配方。 在創建 Recipe 對象的同時創建 Ingredient 對象。

模型.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


序列化程序.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創建一個新的食譜時,沒有關聯的成分。

但是,我似乎無法找到一種方法來保持與食譜相關的成分。

我發現在創建所有未創建的對象之前無法建立多對多關系。 (請參閱關於多對多關系的 Django 文檔頁面。)

這是工作代碼:

序列化程序.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 中工作了,所以請持保留態度:

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

下面是這個問題的一個有用的例子。

像這樣更改那部分代碼:

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

這就是編輯的方法,當你想編輯時會導致錯誤。

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

這是一個帶有示例的鏈接。 此代碼類似於另一個答案,但如果您想嘗試該代碼而沒有任何問題,則可以使用此 repo。 祝你好運! DRF 嵌套序列化程序

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM