2022年8月14日 06:20 by wst
python小技巧在日常开发中, 你是否碰到过这样的问题:
1. mysql中的datetime字段, 用json.dumps的过程中报错, 说不支持这种类型.
2. mysql中的decimal字段, 在用json序列化的过程中,同样报不支持.
场景一:
在电商系统中, 经常需要记录创建时间,比如订单创建时间、用户付款时间等等。当用户查看订单的时候,需要从数据库中取出“时间”返给前端。
在不同web框架中,处理方式也不一样,本人在使用sanic框架的respsonse.json方法时就报了错。
场景二:
在处理和钱相关的数据时,由于python的float会产生数据误差,一般采用decimal类型存储。包括在python中和mysql中。
既然“sanic框架”和“json”包不支持上述情况,那么我们可以定制一下:对decimal类型、datetime类型进行特殊处理。下面分两种情况:json包和sanic框架。
#!/usr/bin/env python
"""
FileName: json_encoder
Author: wst
Email: movingheart000@gmail.com
Date: 2022/8/5 13:31:32
Desc: 能够处理deciaml类型的编码器
"""
import json
import datetime
from decimal import *
class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
# if passed in object is instance of Decimal
# convert it to a string
if isinstance(obj, Decimal):
return str(obj)
if isinstance(obj, datetime.datetime):
return obj.strftime("%Y-%m-%d %X")
# otherwise use the default behavior
return json.JSONEncoder.default(self, obj)
if __name__ == "__main__":
num = Decimal('3.14')
json_str = json.dumps({'salary': num}, cls=DecimalEncoder)
print(json_str) # '{"salary": "3.14"}'
print(type(json_str)) # <class 'str'>
dt = json.dumps({"create_time": datetime.datetime.now()}, cls=DecimalEncoder)
print("dt:", dt) # dt: {"create_time": "2022-08-14 05:54:47"}
print(type(dt)) # <class 'str'>
#!/usr/bin/env python
"""
FileName: pub
Author: wst
Email: movingheart000@gmail.com
Date: 2022/08/13 22:39:29
"""
from sanic import response
from functools import partial
from .json_encoder import DecimalEncoder
json_dumps = partial(dumps, cls=DecimalEncoder)
def resp_json(status: int = RespCode.OK, msg: str = None, data=None, headers: dict = None):
"""
响应json
:param status:返回的状态码
:param msg: 状态解释
:param data: 数据
:param headers:响应头
:return:
"""
res = {"code": status, "msg": RespCode.desc.get(status)}
if msg is not None:
res["msg"] = msg
if data is not None:
res["data"] = data
return response.json(res, headers=headers, dumps=json_dumps)
注:关于partial的用法,参考这里:https://zhuanlan.zhihu.com/p/47124891
如果看完文章,还是不能解决问题,欢迎探讨。v:Beeb2b3