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
相关产品推荐
相关产品推荐

