как сохранить объект ForeignKey и его родительский объект одновременно - PullRequest
0 голосов
/ 29 апреля 2020

Angular 8, Django 3. У меня есть две модели Recipe и Ingredients. Я использую ngModels на внешнем интерфейсе для отправки данных на Django для создания Recipe модели. На одной странице, когда вы нажимаете «отправить», все данные Recipe и Ingredients отправляются на сервер.

Из того, что я прочитал о ManyToOne отношениях, models.ForeignKey должно go на модели, которая является частью "многих". Так что есть «много» * ​​1011 * на Recipe, поэтому у меня есть Foreignkey на Ingredients.

Моя проблема в том, что когда я отправляю все эти данные в 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 данных на бэкэнде, просто не знаю, как их сохранить с помощью Foreignkey для 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.

1 Ответ

1 голос
/ 29 апреля 2020

Вы устанавливаете ингредиенты как read_only , поэтому они не будут созданы. Вам нужно удалить это, если вы хотите сохранить их.

Обновление: также вам необходимо переопределить метод создания. Проверьте Написание методов .create () для вложенных представлений в документах.

Это будет примерно так:

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