Django REST Framework报ManyRelatedManager无法JSON序列化如何解决
问题解决方法
核心问题原因
- 多对多字段
students_in_class配置错误:未添加many=True参数,且设置了read_only=True导致提交的学生ID不会进入校验后的有效数据 - 序列化时直接返回了
ManyRelatedManager管理器对象,DRF无法将该对象转为JSON格式,触发类型错误 - 你修改后的代码存在逻辑错误,将学生ID列表赋值给了地址字段,且多对多字段配置冗余
修复后的完整代码
1. 序列化器代码
class TeacherSerializer(serializers.ModelSerializer): students_in_class = serializers.PrimaryKeyRelatedField( many=True, queryset=Student.objects.all(), required=False ) address = serializers.CharField(required=False) class Meta: model = Teacher fields = ["address","students_in_class"] def update(self, instance, validated_data): # 更新普通字段,不传则保留原值 instance.address = validated_data.get("address", instance.address) # 处理多对多学生关联 students = validated_data.get("students_in_class") if students: # 追加学生用add,覆盖整个学生列表用instance.students_in_class.set(students) instance.students_in_class.add(*students) instance.save() return instance
2. 视图代码
from rest_framework import status class AddtoClassView(APIView): def put(self,request,pk,*args,**kwargs): # 增加教师存在性校验 try: teacher = Teacher.objects.get(id=pk) except Teacher.DoesNotExist: return Response({"message":"教师不存在"}, status=status.HTTP_404_NOT_FOUND) # 增加partial=True支持部分字段更新,不需要每次都传所有字段 serializer = TeacherSerializer(teacher, data=request.data, partial=True) if serializer.is_valid(): serializer.save() return Response({ "message":"学生已添加到班级", "data": serializer.data },status=status.HTTP_200_OK) # 校验失败返回错误信息而非空数据 return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
字段使用说明
PrimaryKeyRelatedField:专门用于处理模型关联字段的序列化/反序列化,会自动校验传入的主键是否存在于指定的queryset中,读操作时自动返回关联对象的主键列表,无需手动转换类型,所有外键、多对多等关联字段的ID交互场景都优先用该字段IntegerField:普通整数字段,不会做关联校验,仅适用于非关联的普通整数属性,不建议用来处理关联模型的ID传参
接口调用说明
调用PUT接口时,传入的body示例如下即可完成学生添加:
{ "students_in_class": [1,2,3] }
数组内为需要添加的学生主键ID。
内容的提问来源于stack exchange,提问作者Reactoo
相关产品推荐
相关产品推荐

