Drf Записываемые вложенные сериализаторы "Это поле обязательно для заполнения".

Вот код: Models.py

class Question(models.Model):
    lesson = models.ForeignKey(Lesson, on_delete=models.CASCADE, related_name='questions')
    question = models.CharField('lesson name', max_length=120)


class Option(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE, related_name='options')
    option = models.CharField('test option', max_length=100)
    correct = models.BooleanField(default=False)

Views.py

class QuestionAPIView(generics.CreateAPIView):
    queryset = Question.objects.all()
    serializer_class = QuestionSerializer

Serializers.py

class OptionSerializer(serializers.ModelSerializer):

    class Meta:
        model = Option
        fields = ('option', 'correct')


class QuestionSerializer(serializers.ModelSerializer):
    options = OptionSerializer(many=True)

    class Meta:
        model = Question
        fields = ('lesson', 'question', 'options')

    def create(self, validated_data):
        options_data = validated_data.pop('options')
        question = Question.objects.create(**validated_data)
        for option_data in options_data:
            Option.objects.create(question=question, **option_data)
        return question

Я пытаюсь создать тестовый вопрос с несколькими вариантами ответов следующим образом:

data = {
    "lesson": 2,
    "question": "This is our first question?",
    "options": [
        {
            "option": "Option 1",
            "correct": True
        },
        {
            "option": "Option 2 ",
            "correct": False
        },
        {
            "option": "Option 3",
            "correct": True
        }
    ]
}

Но в postman и в TestCase у меня есть:

{
    "options": [
        "This field is required."
    ]
}

В чем проблема валидации? Документация здесь https://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers Спасибо.

Хотя я считаю, что required=True внутри OptionSerializer(many=True,required=True) должен решить вашу проблему, если ваш json для OptionSerializer корректен, иначе следующее решение может решить вашу проблему

class QuestionSerializer(serializers.ModelSerializer):
    options = serializers.SerializerMethodField()

    class Meta:
        model = Question
        fields = ('lesson', 'question', 'options')

    def get_options(self, obj):
        options = Option.objects.filter(question=obj)
        serializer = OptionSerializer(options, many=True)
        return serializer.data

    def create(self, validated_data):
        options_data = validated_data.pop('options')
        question = Question.objects.create(**validated_data)
        for option_data in options_data:
            Option.objects.create(question=question, **option_data)
        return question

В моем тестировании это действительно работает отлично. Только обратите внимание на ваш JSON объект, вы использовали True / False как Python boolean varible, а не JSON: (Проверено и с postman, и с DRF Browsable API)

data = {
    "lesson": 2,
    "question": "This is our first question?",
    "options": [
        {
            "option": "Option 1",
            "correct": true
        },
        {
            "option": "Option 2 ",
            "correct": false
        },
        {
            "option": "Option 3",
            "correct": true
        }
    ]
}
Вернуться на верх