Django DRF嵌套序列化器提交多对多关系字段报TypeError问题
问题根源
- 代码首先存在多处拼写错误:
TracksSerializer被误写为TracksSerializar/TracksSerializaer,Album模型名被误写为ALbum,这类拼写问题会先引发基础运行异常,需先统一修正。 - 核心报错来自嵌套创建时的多对多字段处理逻辑错误:DRF序列化器校验完
orders字段的id数组后,会自动将id转换为对应的Orders对象列表存储到validated_data中。你直接将携带Orders对象列表的参数传给Tracks.objects.get_or_create(),但多对多字段不能直接作为模型实例的创建参数,必须等Track实例创建完成后,再调用多对多字段的add()方法单独关联。 - 额外逻辑错误:Album序列化器create方法中循环变量重名(
for tracks in tracks),且调用album.tracks.add(tracks)时传入的是track的字典数据,不是创建完成的Track实例。
修正后的序列化器代码
class TracksSerializer(serializers.ModelSerializer): class Meta: model = Tracks fields = "__all__" # 修正类名拼写 class AlbumSerializer(serializers.ModelSerializer): # 修正序列化器名称拼写 tracks = TracksSerializer(many=True) class Meta: # 修正模型名大小写错误 model = Album fields = '__all__' def create(self, validated_data): tracks_data = validated_data.pop('tracks') album = Album.objects.create(**validated_data) # 修正循环变量名,避免重名 for track_data in tracks_data: # 先将多对多的orders字段弹出,单独处理关联 orders = track_data.pop('orders', []) # 用剩余的普通字段创建/获取Track实例 track, created = Tracks.objects.get_or_create(album=album, **track_data) # 为Track实例关联对应Orders对象 track.orders.add(*orders) # 将Track关联到Album(创建时已传入album参数,本步可省略,保留更稳妥) album.tracks.add(track) return album class OrdersSerializer(serializers.ModelSerializer): class Meta: model = Orders fields = '__all__'
验证方式
提交Album的请求结构保持原有写法即可,示例请求体:
{ "title": "测试专辑", "description": "测试描述", "tracks": [ { "name": "测试曲目", "orders": [2,4] } ] }
内容的提问来源于stack exchange,提问作者user16825896
相关产品推荐
相关产品推荐

