【问题标题】:how to save ForeignKey object and its parent object at the same time如何同时保存 ForeignKey 对象及其父对象
【发布时间】:2020-04-29 14:50:55
【问题描述】:

Angular 8,Django 3。我有两个模型 RecipeIngredients。我在前端使用ngModels 将数据发送到Django 以创建Recipe 模型。在单击“提交”的一个页面上,所有RecipeIngredients 数据都会发送到后端。

从我读到的关于ManyToOne 关系的内容中,models.ForeignKey 应该继续使用属于“许多”的模型。所以每个Recipe 有“很多”Ingredients,所以我在Ingredients 上有Foreignkey

我的问题是当我将所有这些数据发送到 Django 时,我的 Ingredients 没有被创建,因为 RecipeSerializer 上没有 ingredients 字段。

models.py

class Recipe(models.Model):
    name = models.CharField(max_length=30)


class Ingredients(models.Model):
    name = models.CharField(max_length=50)
    recipe = models.ForeignKey(Recipe, related_name='ingredients', on_delete=models.CASCADE)

views.py

class AddRecipe(generics.CreateAPIView):
    serializer_class = RecipeFullSerializer

serializers.py

class IngredientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Ingredients
        fields = ['name']

class RecipeFullSerializer(serializers.ModelSerializer):
    ingredients = IngredientSerializer(many=True, read_only=True)
    class Meta:
        model = Recipe
        fields = ['name', 'ingredients']

样本数据

ingredients: Array(1)
0: {name: "23"}
length: 1
__proto__: Array(0)
name: "23"

我在后端得到一组Ingredients 数据,只是不确定如何使用外键同时将其全部保存到Recipes。我想我可以创建一个自定义视图来为我完成所有这些工作,但我认为会有一个基于类的视图可以做到这一点。

错误

AssertionError: The `.create()` method does not support writable nested fields by default.
Write an explicit `.create()` method for serializer `users.serializers.RecipeFullSerializer`, or set `read_only=True` on nested serializer fields.

【问题讨论】:

  • 请用 JSON 格式重写您的 示例数据

标签: django django-rest-framework many-to-one


【解决方案1】:

您将成分设置为read_only,因此它不会创建它们。如果要保存它们,则需要将其删除。

更新:另外,您需要重写 create 方法。检查文档中的Writing .create() methods for nested representations

应该是这样的:

class RecipeFullSerializer(serializers.ModelSerializer):
    ingredients = IngredientSerializer(many=True)

    class Meta:
        model = Recipe
        fields = ['name', 'ingredients']

    def create(self, validated_data):
        ingredients = validated_data.pop('ingredients')
        recipe = Recipe.objects.create(**validated_data)
        for ingredient in ingredients:
            Ingredient.objects.create(recipe=recipe, **ingredient)

        return recipe

【讨论】:

  • 哇,这是一个很好的收获,但现在我得到了Bad Request Error..
  • 添加一个请求示例,看看你是如何将数据发送到后端的
  • 我编辑了一个请求示例,希望这就是您要找的吗?
  • 为新错误再次编辑,看起来它回答了我的问题,即您不能使用基于类的视图进行嵌套序列化,所以我必须自己编写正确的?
  • 该示例数据格式不正确,因此不是很有用。但是,是的,该错误告诉您需要覆盖序列化程序的默认 create 方法
猜你喜欢
  • 2017-04-12
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多