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

Django中如何向序列化器的ManyToManyField传递主键列表?

问题原因

你当前报错的核心是序列化器字段配置不匹配:
你在UserInterestsSerializer中将categories字段指定为GoalCategorySerializer(many=True),这是嵌套序列化器,反序列化(接收请求参数)时默认要求传入字典格式的分类数据,而你传入的是字符串格式的主键列表,自然触发「期望字典但得到字符串」的报错。

解决方法

如果你只需要通过主键列表关联已存在的GoalCategory记录,不需要通过当前接口新增分类,修改序列化器配置即可,有两种常用方案:


方案1:简化字段,直接接收主键列表

如果接口返回时也只需要返回分类主键,不需要返回分类的详细字段(category、emoji_url),直接把categories字段替换为SlugRelatedField即可:

class UserInterestsSerializer(serializers.ModelSerializer):
    categories = serializers.SlugRelatedField(
        many=True,
        slug_field='category', # 这里填你作为主键传入的字段名,你当前场景就是category
        queryset=GoalCategory.objects.all()
    )

    class Meta:
        model = UserInterests
        fields = ('user', 'categories', 'uuid')

修改后你原来的测试代码不需要改动,直接传字符串列表就可以正常通过验证。


方案2:兼顾读写格式,返回嵌套详情、传入主键列表

如果需要接口返回数据时还是携带分类的完整详情(category、emoji_url),写入时又只需要传入主键列表,重写序列化的输出逻辑即可:

class UserInterestsSerializer(serializers.ModelSerializer):
    # 反序列化阶段用SlugRelatedField接收主键列表
    categories = serializers.SlugRelatedField(
        many=True,
        slug_field='category',
        queryset=GoalCategory.objects.all()
    )

    class Meta:
        model = UserInterests
        fields = ('user', 'categories', 'uuid')
    
    # 序列化输出阶段转换为嵌套格式返回
    def to_representation(self, instance):
        data = super().to_representation(instance)
        data['categories'] = GoalCategorySerializer(instance.categories.all(), many=True).data
        return data

这个方案不需要修改你现有的请求参数和返回字段结构,适配性更强。

内容的提问来源于stack exchange,提问作者user12314098

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:09:04