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
相关产品推荐
相关产品推荐

