Flask自定义json编码器

目录

Flask默认json编码器增加对datetime等类型的编码,详情参看Flask文档:

class flask.json.JSONEncoder(skipkeys=False, _ensureascii=True,_checkcircular=True, _allownan=True, _sortkeys=Falseindent=None,separators=Noneencoding=’utf-8′default=None)
The default Flask JSON encoder. This one extends the default simplejson encoder by also supporting datetime objects, UUID as well as Markup objects which are serialized as RFC 822 datetime strings (same as the HTTP date format). In order to support more data types override the default() method.

我还需要对date、time等类型的编码,所以需要自定义编码器。
参照《Custom Flask JSONEncoder》文章,定义如下的编码器:

class SmsLogReporterApiJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat(' ')  # obj.strftime('%Y-%m-%dT%H:%M:%S')
        elif isinstance(obj, date):
            return obj.strftime('%Y-%m-%d')
        elif isinstance(obj, time):
            return obj.strftime('%H:%M:%S')
        elif isinstance(obj, timedelta):
            return {'day': obj.days, 'seconds': obj.seconds}
        return JSONEncoder.default(self, obj)

在Flask对象中设置json编码器:

app = Flask(__name__)
# ....
app.json_encoder = SmsLogReporterApiJSONEncoder

修改原生json编码器

如果不使用Flask中的json库,也可以设置json编码器。
设置一个编码函数:

def json_default(obj):
    if isinstance(obj, datetime):
        return obj.isoformat(' ')  # obj.strftime('%Y-%m-%dT%H:%M:%S')
    elif isinstance(obj, date):
        return obj.strftime('%Y-%m-%d')
    elif isinstance(obj, time):
        return obj.strftime('%H:%M:%S')
    elif isinstance(obj, timedelta):
        return {'day': obj.days, 'seconds': obj.seconds}
    else:
        raise TypeError('%r is not JSON serializable' % obj)

使用json.dumps编码时,设置default参数即可。

json.dumps(str, default=json_default)