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

DRF创建关联ManyToManyField的Rant对象时报错,求排查解决

问题原因及解决方案

核心问题

错误提示"Expected a list of items but got type \"str\""指向两个关键问题:

  1. 传入的categories参数是字符串类型,而序列化器要求必须是列表格式
  2. 若你是要关联已存在的分类,当前用嵌套CategorySerializer的写法并不适配创建场景

解决方案分两种场景

场景1:关联已存在的Category

如果需求是给新创建的Rant关联已有的分类,无需创建新分类,修改序列化器如下:

class RantSerializer(serializers.ModelSerializer):
    # 用PrimaryKeyRelatedField接收分类ID列表
    categories = serializers.PrimaryKeyRelatedField(many=True, queryset=Category.objects.all())

    class Meta:
        model = Rant
        fields = ('rant', 'slug', 'categories')

此时POST请求的数据格式需为:

{
  "rant": "你的吐槽内容",
  "slug": "your-slug",
  "categories": [1, 3]  // 填入已存在的Category的ID列表
}

场景2:创建Rant的同时创建新Category

如果需要在创建Rant时一并生成新分类,必须重写序列化器的create方法(默认序列化器无法处理多对多关系的嵌套创建),修改后的代码:

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = "__all__"

class RantSerializer(serializers.ModelSerializer):
    categories = CategorySerializer(many=True)

    class Meta:
        model = Rant
        fields = ('rant', 'slug', 'categories')

    def create(self, validated_data):
        # 提取分类数据
        categories_data = validated_data.pop('categories')
        # 创建Rant主对象
        rant = Rant.objects.create(**validated_data)
        # 遍历分类数据,创建或获取分类后关联到Rant
        for category_data in categories_data:
            category, _ = Category.objects.get_or_create(**category_data)
            rant.categories.add(category)
        return rant

此时POST请求的数据必须是分类对象的列表,不能是单个字符串:

{
  "rant": "你的吐槽内容",
  "slug": "your-slug",
  "categories": [
    {"name": "分类1"},
    {"name": "分类2"}
  ]
}

额外检查

无论哪种场景,都要确保POST请求的categories参数是数组格式,绝对不能传入单个字符串(比如"categories": "分类1"这种写法是错误的)。

内容的提问来源于stack exchange,提问作者Vicente Antonio G. Reyes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:52:19