Flask-SQLAlchemy简单封装(三)

1,145 阅读2分钟

这是我参与更文挑战的第27天,活动详情查看: 更文挑战

前言

上文完成了CRUD方法的全部封装

也简单介绍了json和Flask-SQLAlchemy查询结果对象之间的相互转换

但其实还存在一些小小的问题:

  1. 如何返回json结果
  2. 日期格式如何统一
  3. 分页查询的返回结果不优雅

本文将会详细解答这三个问题

方案

如何返回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)

日期格式如何统一

按照一般的思路, 我们都会将后台的日期转换为时间戳传递给前端, 有两种简单的方案:

  1. 保存为时间戳
  2. 手动进行转换处理

第一种显然是不显示的, 在数据库中提供了日期字段, 保存为时间戳有点矫枉过正了

第二种显然是理论上正确的, 但不需要手动这两个字

我们显然是希望在每次转换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的封装已基本完成

当然, 笔者在后续还对这些进行了更加深度一些的封装, 之后有时间会更详细的为各位新人兄弟们进行讲解