Django Rest Framework重写create方法未保存实例字段问题
DRF嵌套序列化器中ForeignKey字段未保存的问题排查与解决
我帮你排查了下代码,问题的核心很明确:你在给quiz_question.correct赋值后,没有调用save()方法将这个修改同步到数据库。
问题原因拆解
当你执行Quiz_Question.objects.create(**validated_data)时,这个实例已经被持久化到数据库里了。之后你给quiz_question.correct赋值,只是在内存中修改了对象的属性,但这个变化并没有自动同步到数据库。所以详情页从数据库读取时,correct字段还是null;而创建页面显示正确,是因为它返回的是内存中还没刷新的实例对象。
修复后的create方法
只需要在赋值correct后,调用quiz_question.save()即可:
def create(self, validated_data): possible_answers_data = validated_data.pop('possible_answers') correct_answers_data = validated_data.pop('correct') quiz_question = Quiz_Question.objects.create(**validated_data) # 先获取或创建正确答案的实例,避免循环里重复判断 correct_answer, _ = Answer_Options.objects.get_or_create(text=correct_answers_data['text']) quiz_question.correct = correct_answer quiz_question.save() # 关键:保存对correct字段的修改 if possible_answers_data: for answer in possible_answers_data: answer, created = Answer_Options.objects.get_or_create(text=answer['text']) quiz_question.possible_answers.add(answer) return quiz_question
额外优化建议
我把正确答案的处理提到了循环外面,这样不用在每次循环里都判断文本是否匹配,能稍微提升一点效率,逻辑也更清晰。
另外,你也可以考虑在创建quiz_question的时候,直接把correct参数传进去(前提是先拿到correct_answer实例),这样就不用额外调用save了:
def create(self, validated_data): possible_answers_data = validated_data.pop('possible_answers') correct_answers_data = validated_data.pop('correct') # 先处理正确答案 correct_answer, _ = Answer_Options.objects.get_or_create(text=correct_answers_data['text']) # 创建quiz_question时直接传入correct参数 quiz_question = Quiz_Question.objects.create(correct=correct_answer, **validated_data) if possible_answers_data: for answer in possible_answers_data: answer, created = Answer_Options.objects.get_or_create(text=answer['text']) quiz_question.possible_answers.add(answer) return quiz_question
这样的写法更简洁,也避免了额外的save操作。
内容的提问来源于stack exchange,提问作者Shashishekhar Hasabnis
相关产品推荐
相关产品推荐

