marshmallow 是一个非常实用的序列化和反序列化框架,由于使用简单、功能丰富被很多开发人员使用,结合 Flask 或 Tornado,可以很轻松使开发人员在开发RESTful风格的API。
下面结合 peewee 的 model 来讲解 marshmallow 的使用
假设有这样两个 model
class Group(BaseModel):
group_type_choices = (
('SuperAdmin', '超级管理员'),
('Admin', '管理员'),
('NormalUser', '普通用户'),
)
group_type = CharField(max_length=128, choices=group_type_choices, verbose_name='用户组类型')
group_type_cn = CharField(max_length=128, verbose_name='用户组类型_cn')
class User(BaseModel):
username = CharField(max_length=32, default='', verbose_name='用户账号')
password = CharField(max_length=255, default='',verbose_name='用户密码')
mobile = CharField(max_length=12, default='', verbose_name='用户手机号')
email = CharField(default='', verbose_name='用户邮箱')
nick_name = CharField(max_length=32, default='', verbose_name='昵称')
region = CharField(max_length=255, default='', verbose_name='地区')
avatar_url = CharField(max_length=255, default='', verbose_name='头像')
gender = IntegerField(choices=((0, '未知'), (1, '男'), (2, '女')), default=0, verbose_name='性别')
birth_date = DateField(verbose_name='生日', null=True)
group = ForeignKeyField(Group, on_delete='RESTRICT', verbose_name='用户组')
想使用marshmallow完成相关操作,需要借助Schemas对象,Schemas的字面意思是模式,在marshmallow中Schemas相当于一个载体,我们要完成的序列化和反序列化操作都是基于Schemas完成的,一个简单的例子介绍Schemas
# 导入相关模块
from marshmallow import Schema, fields
class UserSchema(Schema):
username = fields.String()
mobile = fields.String()
email = fields.Email()
举个例子:我们想要对一个json对象进行数据验证,这个json对象包含哪些key就是Schema中定义的一下变量,再说直白点就是需要进行验证的字段。并且也可以将从数据库中查出的数据对象集进行反序列化为json对象后返回。
从事后端的小伙伴肯定不陌生了,fields就是常说的字段,fields的意义就是针对不同的字段,给它设置上最符合的类型。marshmallow也是如此,我们要想灵活的运用marshmallow就要对一些基本的fields类型了然于心,并且对这些字段的常见属性也要很熟悉。下面就要说一说有哪些常见的fields类型。
String(*, default, missing, data_key, …) 字符串类型
UUID(*, default, missing, data_key, …) UUID字符串类型
Integer(*, strict, **kwargs) 整数类型
Decimal(places, rounding, *, allow_nan, …) 支持Python中的decimal类型,常用语金额类字段
Boolean(*, truthy, falsy, **kwargs) 布尔类型
Float(*, allow_nan, as_string, **kwargs) 浮点类型
DateTime(format, **kwargs) 日期时间类型
Date(format, **kwargs) 日期类型
Email(*args, **kwargs) 邮箱字符串类型
List(cls_or_instance, type], **kwargs) 列表类型,常用于接收数组数据
Dict(keys, type] = None, values, …) 字典类型,常用于接收json类型数据
比较特殊一点的fields类型
Nested(nested, type, str, Callable[[], …) 类似于django中的外键序列化类型,用于使用额外的Schema序列化外键对象
Method(serialize, deserialize, **kwargs) 一个采用Schema方法返回值的字段。类似于django序列化器中的函数字段,可以通过方法构造一个完整的字段返回,该字段可以不是模型中存在的。
Function(serialize, Any], Callable[[Any, …) 接受函数返回值的字段。可将字段通过函数处理后将函数返回值作为该字段的值序列化返回。
fields类型的常用通用属性
default –如果设置,则缺少输入值时,将在序列化过程中使用此值。如果未设置,则如果缺少输入值,则该字段将从串行化输出中排除。可以是值或可调用。
missing -该字段的默认值反序列化如果字段未在输入数据中找到。可以是值或可调用。
validate –反序列化期间调用的验证器或验证器集合。验证程序将字段的输入值作为其唯一参数,并返回一个布尔值。如果返回False,ValidationError则会引发异常。
required –必传验证,如果没有传递该字段将引发默认字段异常。
allow_none –将其设置为在验证/反序列化期间True是否None应被视为有效值。如果missing=None和allow_none未设置,则默认为True。否则,默认值为False。
load_only –如果True在序列化过程中跳过此字段,则其值将出现在序列化数据中。
dump_only –如果True在反序列化过程中跳过此字段,则其值将出现在反序列化的对象中。在HTTP API的上下文中,这有效地将该字段标记为“只读”。
error_messages –值为字典类型,可以用来替代默认的字段异常提示语,例如error_messages={“required”: “功能名称为必传项。”}将默认的必传验证异常语句换成中文。
metadata –要存储为元数据的额外参数。
schema最重要的几个方法之一:load()方法用于验证输入数据的的合法性,当出现异常时会抛出 ValidationError 异常。load()方法会将传入的json类型的字符串默认转换为Python内的dict字典类型,这个过程也被称为反序列化。
验证流程伪代码:
from marshmallow import Schema, fields, ValidationError
class UserSchema(Schema):
username = fields.String()
mobile = fields.String()
email = fields.Email()
try:
data = "{"username":"asd","mobile":"17312345601","email":"test@gmail.com"}" # 假设的json字符串
validataed = UserSchema().load(json.loads(data))
# 此时如果出现验证异常就会抛出 ValidationError
except ValidationError as err:
print(err)