json.loads转换后JSON格式异常?Django REST Framework场景咨询
关于json.loads返回格式的问题解答
嘿,这个坑我之前踩过!先直接给你结论:json.loads返回的这种带单引号、大写布尔值的格式完全正常,但你误解了它的输出类型。
核心原因:json.loads返回的是Python对象,不是JSON字符串
当你执行transaction_json_data = json.loads(request.body)时,你是把第三方发来的标准JSON字符串(双引号、小写true/false)解析成了Python原生的数据结构——比如字典、列表、布尔值这些:
- Python里字符串默认用单引号表示(当然双引号也合法,但打印/转字符串时会优先用单引号)
- Python的布尔值是大写的
True/False,和JSON的小写true/false是不同语言的语法规范
所以transaction_json_data本质是个Python字典(或其他对象),它的字符串表示(比如你打印它看到的内容)是Python语法的格式,不是标准JSON格式。这完全是json.loads的正常行为,它的职责就是完成“JSON字符串 → Python对象”的转换。
为什么Postman重新提交会失败?
你把Python对象的字符串表示(带单引号、大写布尔值)当成标准JSON去提交,但标准JSON有严格的语法要求:
- 字符串必须用双引号
- 布尔值必须是小写的
true/false
DRF的序列化器是按照标准JSON规则验证的,所以自然会判定这种Python风格的格式无效。
解决办法
- 把Python对象转回标准JSON字符串
如果需要把解析后的内容重新生成可提交的标准JSON,用json.dumps()方法,它会把Python对象转换成符合规范的JSON字符串:
# 解析原始JSON为Python对象 transaction_json_data = json.loads(request.body) # 转回标准JSON字符串(双引号、小写布尔值) valid_json_str = json.dumps(transaction_json_data)
把valid_json_str的内容复制到Postman里提交,序列化器就能正常验证了。
- 保存原始请求体用于排查
既然你要存JSON用于排查验证失败的请求,强烈建议直接保存原始的request.body(解码成字符串),而不是保存json.loads后的Python对象的字符串表示。因为原始请求体就是第三方实际发送的标准JSON,后续排查时用它测试最准确,也避免了Python格式和JSON格式的混淆:
# 保存原始JSON字符串到数据库 raw_json = request.body.decode('utf-8') # 不要用 str(transaction_json_data) 来保存
总结
json.loads的行为完全符合预期,它输出的是Python对象而非JSON字符串。你遇到的问题是混淆了Python对象的字符串表示和标准JSON格式,用json.dumps就能转回合法的JSON,保存原始请求体则是更可靠的排查方案。
内容的提问来源于stack exchange,提问作者rcx935
相关产品推荐
相关产品推荐

