You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Rest Framework双层嵌套序列化器实现与报错解决

问题原因

你在QuizSerializer.create方法中直接调用ORM创建Question实例时,传入的参数字典包含answers反向关联嵌套字段,Django ORM不支持直接给反向关联字段赋值,因此触发报错。你单独为QuestionSerializer编写的create方法仅在直接使用QuestionSerializer处理数据时生效,通过ORM直接创建数据不会触发该逻辑。

修复方案

修改QuizSerializer的create方法,手动处理双层嵌套数据即可,完整修改后的serializers.py代码如下:

class AnswerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Answer
        fields = ['id', 'description', 'true_or_false']


class QuestionSerializer(serializers.ModelSerializer):
    answers = AnswerSerializer(many=True)

    class Meta:
        model = Question
        fields = ['id','description','answers']
        read_only_fields = ('quiz',)
    
    def create(self, validated_data):
        answers_data = validated_data.pop('answers')
        question = Question.objects.create(**validated_data)
        for answer in answers_data:
            Answer.objects.create(question=question, **answer)
        return question


class QuizSerializer(serializers.ModelSerializer):
    questions = QuestionSerializer(many=True)
    class Meta:
        model = Quiz
        fields = ['id', 'title', 'questions']
    
    def create(self, validated_data):
        questions_data = validated_data.pop('questions')
        quiz = Quiz.objects.create(**validated_data)
        for question_data in questions_data:
            # 先弹出answers字段,避免ORM识别为反向关联字段报错
            answers_data = question_data.pop('answers')
            # 创建Question实例
            question = Question.objects.create(quiz=quiz, **question_data)
            # 批量创建关联的Answer实例
            Answer.objects.bulk_create([
                Answer(question=question, **answer_data) for answer_data in answers_data
            ])
        return quiz
额外说明
  • 上述修改中使用bulk_create批量创建答案,可以减少数据库查询次数,提升接口性能
  • 如果需要支持PUT/PATCH更新嵌套数据,还需要对应重写序列化器的update方法,处理嵌套字段的新增、修改、删除逻辑
  • 如果你的接口同时支持单独创建Question,也可以直接复用已有的QuestionSerializer.create逻辑,减少重复代码:
def create(self, validated_data):
    questions_data = validated_data.pop('questions')
    quiz = Quiz.objects.create(**validated_data)
    for question_data in questions_data:
        # 注入quiz外键值
        question_data['quiz'] = quiz
        # 复用QuestionSerializer的create逻辑
        QuestionSerializer().create(validated_data=question_data)
    return quiz

内容的提问来源于stack exchange,提问作者Matheus Bachiste Lopes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 21:18:00