这是我参与更文挑战的第27天,活动详情查看: 更文挑战
前言
上文完成了CRUD方法的全部封装
也简单介绍了json和Flask-SQLAlchemy查询结果对象之间的相互转换
但其实还存在一些小小的问题:
- 如何返回json结果
- 日期格式如何统一
- 分页查询的返回结果不优雅
本文将会详细解答这三个问题
方案
如何返回json结果
在Flask中, 为我们提供了一个名为jsonify的函数, 用于将数据内容转换为json字符串
所以我们的接口大致可以写成如下样式:
from flask import request, jsonify
from flask_restx import Namespace, Resource
from .model import User
auth = Namespace('auth', '认证管理')
@auth.route('/login')
class Login(Resource):
def post(self):
params = request.get_json()
user = User.get_by_username(params['username'])
if not check_password_hash(user.password, data['password']):
raise BusinessException('密码错误')
return jsonify(user)
复制代码
日期格式如何统一
按照一般的思路, 我们都会将后台的日期转换为时间戳传递给前端, 有两种简单的方案:
- 保存为时间戳
- 手动进行转换处理
第一种显然是不显示的, 在数据库中提供了日期字段, 保存为时间戳有点矫枉过正了
第二种显然是理论上正确的, 但不需要手动这两个字
我们显然是希望在每次转换json的过程中, 代码可以自动处理日期格式化的问题, 比如Java中的某些注解
其实Flask为我们提供了支持, 即自定义json编码器:
from flask import Flask
from .encoders import MyJSONEncoder
app = Flask(__name__)
app.json_encoder = MyJSONEncoder
复制代码
完成json编码器的替换后, 就来看看我们的编码器是如何处理时间的:
from datetime import datetime
from flask.json import JSONEncoder
class MyJSONEncoder(JSONEncoder):
def default(self, o):
if isinstance(o, datetime):
return str(round(o.timestamp()))
else:
return super().default(o)
复制代码
是不是兄弟们一下就有了很多思路了呢?
分页查询的返回结果不优雅
json编码器都可以自定义, 这个问题会难道我们吗?
其实在分页中, 比较难处理的就是如何将结果对象转换为字典, 且将不能序列化的query
属性去掉
知道如何修改后, 我们可以继续调整json编码器:
from datetime import datetime
from flask.json import JSONEncoder
from flask_sqlalchemy import Pagination
class KoalaJSONEncoder(JSONEncoder):
def default(self, o):
if isinstance(o, datetime):
return str(round(o.timestamp()))
if isinstance(o, Pagination):
temp = o.__dict__
del temp['query']
temp['pages'] = o.pages
return temp
else:
return super().default(o)
复制代码
总结
至此为止, 对于Flask-SQLAlchemy的封装已基本完成
当然, 笔者在后续还对这些进行了更加深度一些的封装, 之后有时间会更详细的为各位新人兄弟们进行讲解
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END