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