Django嵌套序列化器报错:禁止直接赋值关联集合反向侧
解决Django序列化器自定义create时的反向关联赋值错误
错误信息
TypeError: Direct assignment to the reverse side of a related set is prohibited. Use lines.set() instead.
问题原因
在CheatsheetSerializer的create方法中,遍历sections_data时,每个section字典包含了嵌套的lines数据,直接通过Section.objects.create(cheatsheet=cheatsheet, **section)创建实例时,会把lines字段传递给Section模型。但lines是Section与Line的反向关联字段(通过related_name='lines'定义),Django不允许直接对反向关联集合赋值,因此抛出错误。
解决方案
修改CheatsheetSerializer的create方法,利用已定义好的SectionSerializer来处理section及嵌套的lines数据,避免手动传递反向关联字段。
修改后的serializers.py代码:
from rest_framework import serializers from .models import Cheatsheet, Section, Line class LineSerializer(serializers.ModelSerializer): class Meta: model = Line fields = "__all__" class SectionSerializer(serializers.ModelSerializer): lines = LineSerializer(many=True) class Meta: model = Section fields = "__all__" def create(self, validated_data): lines_data = validated_data.pop('lines') section = Section.objects.create(**validated_data) for line in lines_data: Line.objects.create(section=section, **line) return section class CheatsheetSerializer(serializers.ModelSerializer): sections = SectionSerializer(many=True) class Meta: model = Cheatsheet fields = "__all__" def create(self, validated_data): sections_data = validated_data.pop('sections') cheatsheet = Cheatsheet.objects.create(**validated_data) # 修改部分:使用SectionSerializer处理每个section的数据 for section_data in sections_data: section_data['cheatsheet'] = cheatsheet section_serializer = SectionSerializer(data=section_data) section_serializer.is_valid(raise_exception=True) section_serializer.save() return cheatsheet
说明
SectionSerializer已经实现了处理嵌套lines的逻辑,直接复用它可以避免重复代码,同时确保lines数据被正确处理,不会错误传递给Section模型。- 通过给
section_data添加cheatsheet关联,再调用SectionSerializer.save(),即可完成Section及对应Line的创建,同时正确建立与Cheatsheet的关联。
内容的提问来源于stack exchange,提问作者Christian Samaniego
相关产品推荐
相关产品推荐

