You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决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库直接按原样传递字符串?

问题原因与解决方案

核心问题

  1. 用data传字符串时,requests默认会把内容当作application/x-www-form-urlencoded格式处理,即便手动设置Content-Type,也会对字符串做额外编码,导致API接收到的内容不符合预期。
  2. 之前用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 02:55:45