添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
#这里数据库模型使用的SQLAlchemy
class User(Base):
    id = Column(Integer, primary_key=True)
    nickname = Column(String(24), unique=True)
    _password = Column('password', String(100))

一般的玩法就是把对象属性给个都取出来,存放在字典里面,然后用jsonify序列化。这个玩多了,开发也差不多累了,心塞。因为这个方法不能直接序列化对象,那就想办法让它可以就牛逼了。

这里面有两个过程可以优化:

  • 对象快速转字典
  • 对象嵌套快熟序列化
  • flask中的原始基类提供的todict方法

    需要主要的是,它只能把实例属性转化为字段,其他属性并没有。并且我们通常需要对数据模型进行序列化,如果通过这样方式转化里面有很多用不着的属性没办法去掉(这里有点view-model感觉了)。 解决方案demo:

    class User(Base):
        id = Column(Integer, primary_key=True)
        nickname = Column(String(24), unique=True)
        _password = Column('password', String(100))
        #返回对象中的每个属性
        def keys(self):
            #return ['id','nickname']也可以指定序列化指定的字段
            return self.fields
        #通过对象的每个属性获取对应的值
        def __getitem__(self, item):
            return getattr(self, item)
    最后用dict(user)即可
    

    重写jsonify中方法,兼容序列化对象

    解析JSONEncoder中default方法,每当调用jsonify的时候发现有不可序列化的数据时候,会触发此方法,并且是递归调用的。看源码不难理解里面内容。

    def default(self, o):
      if isinstance(o, datetime):
          return http_date(o.utctimetuple())
      if isinstance(o, date):
          return http_date(o.timetuple())
      if isinstance(o, uuid.UUID):
          return str(o)
      if hasattr(o, '__html__'):
          return text_type(o.__html__())
      return _json.JSONEncoder.default(self, o)
    

    打造高可用的序列化器,结合上面对象转字典,完美解决jsonify可序列化对象

    from flask import Flask as _Flask
    from flask.json import JSONEncoder as _JSONEncoder
    from datetime import date
    #继承_JSONEncoder重写default,每当发送有不能序列化的类型时,在这里就可以参考源码进行添加即可。
    class JSONEncoder(_JSONEncoder):
        def default(self, o):
            if hasattr(o, 'keys') and hasattr(o, '__getitem__'):
                return dict(o)
            if isinstance(o, date):
                return o.strftime('%Y-%m-%d')
            raise Error()
    #重写flask,把新的JSONEncoder赋值给flask对象,这样新的才能生效
    class Flask(_Flask):
        json_encoder = JSONEncoder