Django REST API PATCH请求报错:TypeError: expected string or buffer
解决Django PATCH请求中的TypeError问题
咱们先从你遇到的TypeError: expected string or buffer报错入手分析,结合你贴的代码片段,能发现几个关键问题,咱们一步步来梳理:
问题根源拆解
- 低级语法错误:你写的
elif request.method = 'PATCH':用了单等号赋值,这会直接把字符串'PATCH'塞给request.method,完全不是判断请求方法的逻辑,必须改成双等号==。 - 序列化器使用逻辑错误:处理PATCH更新时,你只传了
data和partial=True,但没传入要修改的目标instance——当前写法相当于要创建新对象,而不是更新已有对象。 - 字段值获取方式错误:
serializer['time']返回的是序列化器的字段对象,不是实际的time字段值,直接把它赋值给obj.time会导致类型不匹配,触发时间格式验证时的字符串/缓冲区预期错误。 - 未验证的原始数据查询:直接用
request.data['start_time']查数据库很危险,这个值没经过序列化器验证,格式可能不对,而且如果前端漏传这个字段会直接抛出KeyError。
修正后的views.py代码片段
elif request.method == 'PATCH': # 先初始化序列化器验证所有传入数据 serializer = TABLESerializer(data=request.data, partial=True) if serializer.is_valid(): # 从验证通过的有效数据里取start_time,避免原始数据的格式问题 try: obj = TABLE.objects.get(start_time=serializer.validated_data['start_time']) except TABLE.DoesNotExist: return Response({"error": "目标对象不存在"}, status=status.HTTP_404_NOT_FOUND) # 取验证后的time有效值赋值 obj.time = serializer.validated_data['time'] obj.save() # 序列化更新后的对象再返回,确保响应数据准确 updated_serializer = TABLESerializer(obj) return Response(updated_serializer.data, status=status.HTTP_200_OK) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
额外优化建议
- 用DRF自带视图简化代码:如果你的视图是基于类的,推荐直接用
UpdateAPIView,它会自动处理PATCH请求,减少重复造轮子:from rest_framework.generics import UpdateAPIView class TABLEUpdateView(UpdateAPIView): queryset = TABLE.objects.all() serializer_class = TABLESerializer lookup_field = 'start_time' # 指定用start_time作为查询匹配字段 - 强化字段验证:确保
TABLESerializer里的start_time和time字段用了正确的字段类型(比如DateTimeField/TimeField),并配置合适的格式验证规则,提前拦截非法数据。 - 异常全覆盖:除了
DoesNotExist,还可以考虑捕获MultipleObjectsReturned异常,避免多个对象匹配start_time时的报错。
这样调整后,应该就能解决你遇到的类型错误,同时让PATCH请求的处理逻辑更健壮。
内容的提问来源于stack exchange,提问作者Marcin Ginszt
相关产品推荐
相关产品推荐

