如何解决Python3 requests库发送批量PATCH请求列表数据失败问题?
问题背景
我正在使用一个支持通过PATCH请求批量部分更新对象的API端点,该端点接受JSON格式的字典列表。以下curl命令可成功执行并返回预期的更新对象:
$ curl -X PATCH \ -H "Authorization: Token abcde" \ -H "Content-Type: application/json" \ "example.com/api/objects" \ --data="[{'id': 1, 'value': 100}, {'id': 2, 'value': 200}]"
但以下Python3代码片段执行失败:
import requests headers = { "Authorization": "Token abcde", "Content-Type": "application/json" } data = "[{'id': 1, 'value': 100}, {'id': 2, 'value': 200}]" response = requests.patch("example.com/api/objects", headers=headers, data=data) if response.status_code != 200: print(f"{response.status_code}: {response.reason}") print(response)
返回结果:
400: Bad Request {'non_field_errors': ['Expected a list of items but got type "dict".']}
我尝试过:
- 将代码改为用
json参数传入字符串data - 将
data改为Python列表对象,分别传入data和json参数
均返回400错误。请问哪里操作有误?如何让requests库直接按原样传递字符串?
问题原因与解决方案
核心问题
- 用
data传字符串时,requests默认会把内容当作application/x-www-form-urlencoded格式处理,即便手动设置Content-Type,也会对字符串做额外编码,导致API接收到的内容不符合预期。 - 之前用Python列表传
json参数失败,大概率是请求URL缺少http:///https://协议头,或者手动设置的Content-Type与requests自动生成的头存在冲突。
正确解决方法
方法1:直接传递原始JSON字符串(按原样发送)
把字符串转为字节类型,让requests完全不做额外处理,同时确保URL带协议头:
import requests headers = { "Authorization": "Token abcde", "Content-Type": "application/json" } data = "[{'id': 1, 'value': 100}, {'id': 2, 'value': 200}]" # 转为字节后传入data参数,避免requests编码处理 response = requests.patch("http://example.com/api/objects", headers=headers, data=data.encode('utf-8')) if response.status_code != 200: print(f"{response.status_code}: {response.reason}") print(response.json())
方法2:用Python列表+json参数(推荐)
直接传Python列表到json参数,移除手动设置的Content-Type——requests会自动处理JSON序列化并设置正确的请求头:
import requests headers = { "Authorization": "Token abcde" } data = [{'id': 1, 'value': 100}, {'id': 2, 'value': 200}] # json参数自动完成序列化和Content-Type设置 response = requests.patch("http://example.com/api/objects", headers=headers, json=data) if response.status_code != 200: print(f"{response.status_code}: {response.reason}") print(response.json())
为什么curl能成功?
curl的--data参数会直接把字符串作为请求体发送,不会做额外编码,加上正确设置的Content-Type头,API就能正确解析内容。
内容的提问来源于stack exchange,提问作者Janna
相关产品推荐
相关产品推荐

