Flask设置返回json格式数据

本文介绍如何在Flask应用中正确返回JSON格式的数据,包括使用jsonify模块、自定义Response类及force_type方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://blog.youkuaiyun.com/angus_17/article/details/80455838

 

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中直接返回listdict是不行的,如

Python

 
  1. from flask import Flask

  2.  
  3. app = Flask(__name__)

  4.  
  5.  
  6. @app.route('/')

  7. def root():

  8. t = {

  9. 'a': 1,

  10. 'b': 2,

  11. 'c': [3, 4, 5]

  12. }

  13. return t

  14.  
  15. if __name__ == '__main__':

  16. app.debug = True

  17. app.run()

这样访问会直接提示

<code class="language-plain" style="font-family:Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;font-size:13.6px;background:transparent;margin:0px;word-spacing:normal;line-height:inherit;border:0px;">TypeError: 'dict' object is not callable<span class="line-numbers-rows" style="font-size:13.6px;width:3em;letter-spacing:-1px;border-right:1px solid rgb(153,153,153);"><span></span></span></code>

其原因是Flask并不会将listdict默认转换为json格式。

解决方法

HTTP返回json格式数据主要有两个方面:

  1. 数据本身为json格式;
  2. Content-Type声明为json格式。

使用标准库json

比较常见的是采用标准库json进行格式转换:

Python

 
  1. from flask import Flask

  2. import json

  3.  
  4. app = Flask(__name__)

  5.  
  6.  
  7. @app.route('/')

  8. def root():

  9. t = {

  10. 'a': 1,

  11. 'b': 2,

  12. 'c': [3, 4, 5]

  13. }

  14. return json.dumps(t)

  15.  
  16. if __name__ == '__main__':

  17. app.debug = True

  18. app.run()

这样当访问时即能够正常得到json数据。但这么做有一个缺点,就是HTTP返回的Content-Type仍然是text/html,即HTTP认为内容是HTML。

声明Content-Type为json格式

在上面的解决方法上作一个加强,手动指定其Content-Typeapplication/json,通常采用的是修改Flask中的Response模块:

Python

 
  1. from flask import Flask, Response

  2. import json

  3.  
  4. app = Flask(__name__)

  5.  
  6.  
  7. @app.route('/')

  8. def root():

  9. t = {

  10. 'a': 1,

  11. 'b': 2,

  12. 'c': [3, 4, 5]

  13. }

  14. return Response(json.dumps(t), mimetype='application/json')

  15.  
  16. if __name__ == '__main__':

  17. app.debug = True

  18. app.run()

这样不仅HTTP返回的内容是json,而且返回的Content-Type也是application/json了。

使用Flask的jsonify模块

实际上flask已经为json准备了专门的模块:jsonifyjsonify不仅会将内容转换为json,而且也会修改Content-Typeapplication/json

Python

 
  1. from flask import Flask, jsonify

  2.  
  3. app = Flask(__name__)

  4.  
  5.  
  6. @app.route('/')

  7. def root():

  8. t = {

  9. 'a': 1,

  10. 'b': 2,

  11. 'c': [3, 4, 5]

  12. }

  13. return jsonify(t)

  14.  
  15. if __name__ == '__main__':

  16. app.debug = True

  17. 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()方法尝试处理后,再决定报错或通过。直接看例子吧。

Python

 
  1. from flask import Flask, Response, jsonify

  2.  
  3. class MyResponse(Response):

  4. @classmethod

  5. def force_type(cls, response, environ=None):

  6. if isinstance(response, (list, dict)):

  7. response = jsonify(response)

  8. return super(Response, cls).force_type(response, environ)

  9.  
  10. app = Flask(__name__)

  11. app.response_class = MyResponse

  12.  
  13. @app.route('/')

  14. def root():

  15. t = {

  16. 'a': 1,

  17. 'b': 2,

  18. 'c': [3, 4, 5]

  19. }

  20. return t

  21.  
  22. if __name__ == '__main__':

  23. app.debug = True

  24. app.run()

或者还可以以继承的方式来实现自定义Response,如:

Python

 
  1. from flask import Flask, Response, jsonify

  2.  
  3. class MyResponse(Response):

  4. @classmethod

  5. def force_type(cls, response, environ=None):

  6. if isinstance(response, (list, dict)):

  7. response = jsonify(response)

  8. return super(Response, cls).force_type(response, environ)

  9.  
  10. class MyFlask(Flask):

  11. response_class = MyResponse

  12.  
  13. app = MyFlask(__name__)

  14.  
  15. @app.route('/')

  16. def root():

  17. t = {

  18. 'a': 1,

  19. 'b': 2,

  20. 'c': [3, 4, 5]

  21. }

  22. return t

  23.  
  24. if __name__ == '__main__':

  25. app.debug = True

  26. app.run()

 
  1.  
  2.  

 

转载: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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值