DRF提交多对多字段数据时出现ManyRelatedManager无法JSON序列化报错
问题原因
你遇到的报错有两个核心诱因:
- 序列化器中
skill字段设置了read_only=True,仅支持序列化返回,不会处理你提交的多对多字段数据,提交的skill参数会被直接忽略。 - 视图逻辑中你直接把
professional.skill这个多对多关系管理器对象塞入了返回值,Django的关系管理器本身不是可被JSON序列化的列表/字典结构,直接返回就会触发ManyRelatedManager is not JSON serializable报错。
另外你的代码还存在两处冗余/错误:序列化器中fields = fields =是笔误,serializer.save()之后不需要再手动调用professional.save()重复保存。
解决步骤
1. 修改序列化器,支持多对多字段读写
拆分多对多字段的读写逻辑,读的时候返回Skill的完整序列化信息,写的时候通过主键接收关联的技能ID:
class ProfessionalSerializer(serializers.ModelSerializer): profilePicture = serializers.ImageField(allow_empty_file=True, use_url='professional/profiles', required=False) # 读场景:返回技能完整信息 skill = SkillSerializer(many=True, read_only=True) # 写场景:接收技能ID,映射到模型的skill字段 skill_ids = serializers.PrimaryKeyRelatedField( many=True, queryset=Skill.objects.all(), write_only=True, source='skill' ) class Meta: model = Professionals fields = ['first_name', 'last_name', 'profilePicture', 'skill', 'skill_ids']
2. 修正视图逻辑,避免直接返回管理器对象
直接使用序列化器处理后的数据作为返回结果,不需要手动拼接返回字段,同时补充错误场景的状态码:
class ProfessionalProfileUpdateView(APIView): permission_classes = (IsAuthenticated,IsProfessionalUser,) def put(self, request): # 加partial参数支持部分字段更新 serializer = ProfessionalSerializer(data=request.data, instance=request.user.professional, partial=True) if serializer.is_valid(): serializer.save() return JsonResponse({ 'message': "资料更新成功", "success" : True, "result" : serializer.data, "status" : status.HTTP_200_OK }) return JsonResponse({ 'message': "参数错误", "success" : False, "errors": serializer.errors, "status" : status.HTTP_400_BAD_REQUEST }, status=status.HTTP_400_BAD_REQUEST)
3. 调整请求参数格式
提交的时候直接传skill_ids数组即可,不需要嵌套对象:
{ "first_name":"jhon", "last_name":"doe", "skill_ids":[1] }
内容的提问来源于stack exchange,提问作者july
相关产品推荐
相关产品推荐

