Flask设置返回json格式数据
问题描述
在Flask中直接返回list或dict是不行的,如
from flask import Flask
app = Flask(__name__)
@app.route('/')
def root():
t = {
'a': 1,
'b': 2,
'c': [3, 4, 5]
}
return t
if __name__ == '__main__':
app.debug = True
app.run()
这样访问会直接提示
TypeError: 'dict' object is not callable
其原因是Flask并不会将list或dict默认转换为json格式。
解决方法
HTTP返回json格式数据主要有两个方面:
- 数据本身为json格式;
Content-Type声明为json格式。
使用标准库json
比较常见的是采用标准库json进行格式转换:
from flask import Flask
import json
app = Flask(__name__)
@app.route('/')
def root():
t = {
'a': 1,
'b': 2,
'c': [3, 4, 5]
}
return json.dumps(t)
if __name__ == '__main__':
app.debug = True
app.run()
这样当访问时即能够正常得到json数据。但这么做有一个缺点,就是HTTP返回的Content-Type仍然是text/html,即HTTP认为内容是HTML。
声明Content-Type为json格式
在上面的解决方法上作一个加强,手动指定其Content-Type为application/json,通常采用的是修改Flask中的Response模块:
from flask import Flask, Response
import json
app = Flask(__name__)
@app.route('/')
def root():
t = {
'a': 1,
'b': 2,
'c': [3, 4, 5]
}
return Response(json.dumps(t), mimetype='application/json')
if __name__ == '__main__':
app.debug = True
app.run()
这样不仅HTTP返回的内容是json,而且返回的Content-Type也是application/json了。
使用Flask的jsonify模块
实际上flask已经为json准备了专门的模块:jsonify。jsonify不仅会将内容转换为json,而且也会修改Content-Type为application/json。
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/')
def root():
t = {
'a': 1,
'b': 2,
'c': [3, 4, 5]
}
return jsonify(t)
if __name__ == '__main__':
app.debug = True
app.run()
自定义Flask的Response,使用force_type()(2017.11.9更新)
对于某些特殊的情况,可能并不想每个返回json数据的方法都使用jsonify()包起来,那有没有什么“非侵入式”的方法实现jsonify()的功能呢?其实是有的,不过这个方法相对比较高端。
Flask返回的内容实际是Response对象,return语句的内容实际是交给Response处理后才输出由HTTP返回的;也就是说,之前直接返回dict报错TypeError: 'dict' object is not callable也是Response干的。那么只需要在Response处理如dict等“非法”数据是,告诉Response该怎么做就好了,这里就是用到了其force_type()方法了,所有不能处理的数据,都由force_type()方法尝试处理后,再决定报错或通过。直接看例子吧。
from flask import Flask, Response, jsonify
class MyResponse(Response):
@classmethod
def force_type(cls, response, environ=None):
if isinstance(response, (list, dict)):
response = jsonify(response)
return super(Response, cls).force_type(response, environ)
app = Flask(__name__)
app.response_class = MyResponse
@app.route('/')
def root():
t = {
'a': 1,
'b': 2,
'c': [3, 4, 5]
}
return t
if __name__ == '__main__':
app.debug = True
app.run()
或者还可以以继承的方式来实现自定义Response,如:
from flask import Flask, Response, jsonify
class MyResponse(Response):
@classmethod
def force_type(cls, response, environ=None):
if isinstance(response, (list, dict)):
response = jsonify(response)
return super(Response, cls).force_type(response, environ)
class MyFlask(Flask):
response_class = MyResponse
app = MyFlask(__name__)
@app.route('/')
def root():
t = {
'a': 1,
'b': 2,
'c': [3, 4, 5]
}
return t
if __name__ == '__main__':
app.debug = True
app.run()
转载:https://www.polarxiong.com/archives/Flask%E8%AE%BE%E7%BD%AE%E8%BF%94%E5%9B%9Ejson%E6%A0%BC%E5%BC%8F.html
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)