jsonify的改进
一. json和jsonify
二. 改进的jsonify
三. 使用
一. json和jsonify
json.dumps需要指定返回类型:
t = {
#...
}
return Response(json.dumps(t), mimetype='application/json')
jsonify
默认将返回的类型指定成了application/json
:
t = {
#...
}
return jsonify(t), 200
但是在使用默认情况下, jsonify
对于很多类型的数据是无法序列化的(当然json.dumps
也不行), 比如时间类型的字典, model的实例对象.
二. 改进的jsonify
如果jsonify
不知道如何序列化指定的对象, 程序便会调用JSONEncode
的defualt
方法:
# 源码部分
class JSONEncoder(_json.JSONEncoder):
def default(self, o):
# ...
if isinstance(o, datetime):
return http_date(o.utctimetuple())
if isinstance(o, date):
return http_date(o.timetuple())
if isinstance(o, uuid.UUID):
return str(o)
if hasattr(o, '__html__'):
return text_type(o.__html__())
return _json.JSONEncoder.default(self, o)
#...
其中参数o
便是需要序列化的对象.
因此可以重新定义这个default
方法, 使jsonify支持对sqlalchemy
实例和datetime
类型数据的序列化:
在合适的位置引入并重写:
from flask.json import JSONEncoder as _JSONEncoder
class JSONEncoder(_JSONEncoder):
"""重写对象序列化, 当默认jsonify无法序列化对象的时候将调用这里的default"""
def default(self, o):
if hasattr(o, 'keys') and hasattr(o, '__getitem__'):
return dict(o)
if isinstance(o, date):
# 也可以序列化时间类型的对象
return o.strftime('%Y-%m-%d')
raise ServerError()
- 注:
dict(o)
用到了对象转字典, 其中ServerError也是自定义的异常.
重写后必须指定flask的json_encoder:
from flask import Flask as _Flask
class Flask(_Flask):
json_encoder = JSONEncoder
实例化flask对象的时候, 不要使用原版的Flask类, 而是使用刚刚改进后的class Flask(_Flask):.
, 直接app = Flask(__name__)
即可.
三. 使用
改进后的jsonify已经支持对时间和model对象的序列化
from flask import jsonify
#...
books = Book.query.all()
return jsonify(books)