Flask Python API如何生成指定格式的JSON响应?
解决Flask API返回嵌套结构JSON的问题
问题描述
我在基于Flask的Python API项目中,需要返回如下格式的JSON响应:
{ "images": [ { "transaction": { "message": "match found", "status": "success", "subjectId": 79, "confidence": 0.56 } } ] }
这个响应里,images是列表类型,每个列表元素是包含transaction字典的对象,属于嵌套的列表字典结构。
我写了以下代码尝试实现:
@app.route('/api/v1/face/recognize', methods=['POST']) def recognize(): """ SOME CODE """ images = [] transaction = dict() transaction['status'] = 'success' transaction['message'] = "match found" transaction['subjectId'] = 79 transaction['confidence'] = 0.56 images.append(transaction) return jsonify(images), 200
但实际得到的响应却是:
[ { "confidence": 0.56, "message": "match found", "status": "success", "subject_id": 79 } ]
和预期格式不符,不知道怎么调整才能生成目标响应格式。
解决方案
哦,我看到问题所在了,你的响应和预期不符主要是两个原因:
- 嵌套结构没构建正确:你现在是直接把
transaction字典塞进了images列表,但预期的结构里,images的每个元素应该是一个包含transaction键的字典,而不是transaction本身。 - 键名被自动转换了:Flask的
jsonify默认会把驼峰命名的键(比如subjectId)转换成下划线分隔的格式(变成subject_id),这也导致了和预期的差异。
调整后的代码
这里给你两种可行的修改方式,选一种适合你的就行:
方式一:修改Flask配置,用jsonify返回
from flask import Flask, jsonify app = Flask(__name__) # 关键配置:禁用jsonify自动转换驼峰键为下划线 app.config['JSON_KEYS_CAMEL_CASE'] = False # 可选:关闭自动美化格式,保持紧凑输出 app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False @app.route('/api/v1/face/recognize', methods=['POST']) def recognize(): """ SOME CODE """ # 先构建transaction字典 transaction = { 'status': 'success', 'message': "match found", 'subjectId': 79, 'confidence': 0.56 } # 构建正确的嵌套结构:images列表里是包含transaction的字典 response_data = { 'images': [{'transaction': transaction}] } # 用jsonify返回顶层字典 return jsonify(response_data), 200
方式二:用标准库json.dumps手动序列化(更灵活)
如果你的Flask版本不支持JSON_KEYS_CAMEL_CASE配置,或者想完全控制序列化过程,可以用这种方式:
from flask import Flask import json app = Flask(__name__) @app.route('/api/v1/face/recognize', methods=['POST']) def recognize(): """ SOME CODE """ transaction = { 'status': 'success', 'message': "match found", 'subjectId': 79, 'confidence': 0.56 } response_data = { 'images': [{'transaction': transaction}] } # 手动序列化并返回响应 return app.response_class( response=json.dumps(response_data), status=200, mimetype='application/json' )
为什么这样改?
- 结构修正:原来的代码直接把
transaction加到images列表里,现在我们先创建一个{'transaction': transaction}的字典,再把这个字典放进images列表,最后把images作为键放在顶层字典中,这样就完全匹配了你想要的嵌套结构。 - 键名保留:第一种方式通过修改Flask的配置,让
jsonify不再自动转换键名格式;第二种方式直接使用Python标准库的json.dumps,它不会修改你的键名,能完全保留subjectId的写法。
这样调整后,你就能得到完全符合预期的JSON响应啦!
内容的提问来源于stack exchange,提问作者S Andrew




