关于python:以整洁的方式显示从Flask返回的JSON

Display JSON returned from Flask in a neat way

我正在使用Flask创建一个API,并具有以下代码:

1
2
3
4
@app.route('/<major>/')
def major_res(major):
    course_list = list(client.db.course_col.find({"major": (major.encode("utf8","ignore").upper())}))
    return json.dumps(course_list, sort_keys=True, indent=4, default=json_util.default)

在浏览器中查看/csci/时,输出如下所示:

1
[{"course":"CSCI052","description":"Fundamentals of Computer Science. A solid foundation in functional programming, procedural and data abstraction, recursion and problem-solving. Applications to key areas of computer science, including algorithms and complexity, computer architecture and organization, programming languages, finite automata and computability. This course serves the same role as HM 60 as a prerequisite for upper-division computer science courses at any of the Claremont Colleges. Prerequisite: 51.","instructor":"Bull, Everett L.,, Jr.","name":" Fundamentals of Computer Science","number": 52,"school":"PO" }]

如何返回此字典,以便每个键和值都在各自的行上?


Flask提供jsonify()为方便:

1
2
3
4
5
6
from flask import jsonify

@app.route("/<major>/")
def major_res(major):
    course_list = list(client.db.course_col.find({"major": major.upper()}))
    return flask.jsonify(**course_list)

这将返回jsonify的args作为JSON表示,并且与您的代码不同,它将发送正确的Content-Type标头:application/json。注意文档对格式的看法:

This function's response will be pretty printed if the JSONIFY_PRETTYPRINT_REGULAR config parameter is set to True or the Flask app is running in debug mode. Compressed (not pretty) formatting currently means no indents and no spaces after separators.

不在调试模式下时,响应将接收非精美打印的JSON。这应该不成问题,因为不需要对用于JavaScript消耗的JSON进行格式化(这只是通过网络发送的额外数据),并且大多数工具格式都是自己接收JSON的。

如果您仍然想使用json.dumps(),则可以通过返回Responsecurrent_app.response_class()来发送适当的模仿类型。

1
2
3
4
5
6
from flask import json, current_app

@app.route("/<major>/")
def major_res(major):
    course_list = list(client.db.course_col.find({"major": major.upper() }))
    return current_app.response_class(json.dumps(course_list), mimetype="application/json")

有关差异的更多信息:

  • json.dumps与flask.jsonify
  • flask.json模块文档

在Flask 1.0之前,JSON处理有所不同。 jsonify将尝试检测请求是否为AJAX,如果不是,则返回漂亮的打印内容。因为它不可靠,所以将其删除。 jsonify出于安全原因,仅允许将dicts作为顶级对象。这不再适用于现代浏览器。


如果由于某种原因您需要重写flask.jsonify(例如,添加自定义编码器),则可以使用以下方法来实现,该方法实现了提到的安全修复程序@phpmycoder:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from json import dumps
from flask import make_response

def jsonify(status=200, indent=4, sort_keys=True, **kwargs):
  response = make_response(dumps(dict(**kwargs), indent=indent, sort_keys=sort_keys))
  response.headers['Content-Type'] = 'application/json; charset=utf-8'
  response.headers['mimetype'] = 'application/json'
  response.status_code = status
  return response

app.route('/<major>/')
def major_res(major):
 course = client.db.course_col.find({"major": (major.encode("utf8","ignore").upper())})
 return jsonify(**course)

app.route('/test/')
def test():
 return jsonify(indent=2, sort_keys=False, result="This is just a test")

响应:

1
2
3
4
5
6
7
8
{
   "course":"CSCI052",
   "description":"Fundamentals of Computer Science. A solid foundation in functional programming, procedural and data abstraction, recursion and problem-solving. Applications to key areas of computer science, including algorithms and complexity, computer architecture and organization, programming languages, finite automata and computability. This course serves the same role as HM 60 as a prerequisite for upper-division computer science courses at any of the Claremont Colleges. Prerequisite: 51.",
   "instructor":"Bull, Everett L.,, Jr.",
   "name":" Fundamentals of Computer Science",
   "number": 52,
   "school":"PO"
}

有关使用自定义json编码器的示例,请参见我的其他答案