正在用Flask写个小项目,要实现将自定义类型转化成json格式。Flask一般用jsonify来使接口返回json数据,实现一个Flask内使用的JSONEncoder。
from flask.json import JSONEncoder
#编写自己的json编码器,并继承原有的
class MyJSONEncoder(JSONEncoder):
#在jsonify中不能直接序列化该类型的时候,才会调用default方法,并进入分类执行
def default(self, obj):
if isinstance(obj, EqltByGene):
#自定义返回字典
return {
'gene_id': obj.gene_id,
'gene_symbol': obj.gene_symbol,
'p_value': obj.p_value,
}
return super(MyJSONEncoder, self).default(obj)
app = Flask(__name__)
app.json_encoder = MyJSONEncoder #将自定义的json编码器赋给flask原有的
这样在使用jsonify的时候,就可以将MyObject类型的实例转化到json格式。
问题思考:
- 如果项目中有很多自定义Class,都有这个需求,JSONEncoder的实现似乎会很丑陋,有什么好的方式?
- 同一个Class在不同的场景,json后要保留的字段差别如果很大,该如果实现?
对该问题的实现,可以采用以下方式:
#在模型对象中重写dict方法
class User(Base):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(50), unique=True, nullable=False)
nickname = db.Column(db.String(24), unique=True)
auth = db.Column(db.SmallInteger, default=1) # 1是普通用户,2是管理员
_password = db.Column('password', db.String(100))
#自定义将模型对象转成dict ,即dict(user)
#dict(user),会先调用keys方法,这里重写,自定义获取返回的字段
def keys(self):
return ['id', 'email', 'nickname', 'auth']
# dict(user)获取完字段后,会取出对应字段的值,这里使用__getitem__,这里getattr(self, item)拿到值信息,item为key名
def __getitem__(self, item):
return getattr(self, item)
以上的keys和getitem方法,会在自定义的jsonencoder方法中dict(对象)时候调用,如下:
#自定义json方法,在方法中实现对象转字典返回,这需要在模型对象中实现对应dict方法
class JSONEncoder(_JSONEncoder):
def default(self, o):
return dict(o)
调用方法如:
def get_user(uid):
user = User.query.get_or_404(uid)
return jsonify(user)
所以这样就实现了jsonencoder将对象转化成字典,然后直接jsonnfy调用序列化。并且复用性强,在模型中定义dict调用的方法,使得转化的字典key可以控制。
版权属于:Jolly
本文链接:https://totoro.site/index.php/archives/40/
关于转载:原创文章,禁止转载