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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 12:24:03