flask序列化框架之marshmallow详解

沈畅
2023-12-01

前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

marshmallow

https://marshmallow.readthedocs.io/en/latest/

marshmallow是一个ORM / ODM /与框架无关的库,用于将复杂的数据类型与Python数据类型相互转换

简而言之,用以实现序列化反序列化


pip3 install -U marshmallow

序列化

序列化首先需要对应model模型类建立序列化类对象

from marshmallow import Schema, fields

class UsersSchema(Schema):
    id = fields.Integer()
    name = fields.String()

序列化使用schema中的dump()dumps()方法

  • dump: 实现obj -> dict

  • dumps: 实现 obj -> string

由于Flask能直接序列化dict,所以通常Flask与Marshmallow配合序列化时,用 dump()方法即可


使用序列化器对象,首先初始化序列化类对象实例,然后使用dump方法即可,如果是多条数据,那么可以加上many=True参数

class Index(Resource):
    schmea = UsersSchema()

    def get(self):
        model = Users.query.all()
        data = self.schmea.dump(model, many=True)
        return data

反序列化

反序列化基于schema中的load()loads()方法

  • load: 方法将一个传入的dict,结合schema的约定,再转换为一个dict

  • loads: 方法的传入参数是json格式的string,同样将传入数据转换为符合规范的dict

调用loadloads方法时,会执行下面提到的数据校验,所以在开发RESTful API时,对传入数据执行loadloads方法是必要的


user = {
  	"name": "test",
}
data = self.schmea.load(user)
return data

如果希望不只是反序列化成为个简单的字典,而是直接成为数据库的一条数据,那么需要重新定义反序列化对象的方法,并且使用post_load装饰器装饰

from marshmallow import Schema, fields, post_load

class UsersSchema(Schema):
    id = fields.Integer()
    name = fields.String()

    @post_load
    def make_user(self, data, **kwargs):
        user = Users(**data)
        db.session.add(user)
        db.session.commit()
        return user

这样每次调用load()方法时,会按照make_user的逻辑,返回一个User类对象

schema = UsersSchema()
user = {
  "name": "test"
}
data = schema.load(user)  # 这就是反序列化操作

还支持多数据批量反序列化

user1 = User(name="Mick", email="mick@stones.com")
user2 = User(name="Keith", email="keith@stones.com")
users = [user1, user2]
schema = UserSchema(many=True)
result = schema.dump(users)

读写分离字段

要想实现read_onlywrite_only属性来区别字段在使用过程中是否用于反序列化或序列化,可以通过dump_onlyload_only来完成

class UserSchema(Schema):
    name = fields.Str()
    # password is "write-only"
    password = fields.Str(load_only=True)
    # created_at is "read-only"
    created_at = fields.DateTime(dump_only=True)
 类似资料: