DRF Writable nested serializers "This field is required."

Question:

Here’s the code.

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

I’m trying to create a test question with a few options for answers like this:

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
        }
    ]
}

But in postman and in the TestCase I’ve got:

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

What is the problem of validation?

Here’s the Documentation:

https://www.django-rest-framework.org/api-guide/relations/#writable-nested-serializers

Asked By: Anna Berezko

||

Answers:

It does work perfectly in my testing. Just note your JSON object, you used True / False as Python boolean varible not JSONs:
(Tested both with postman and 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
        }
    ]
}
Answered By: Niko