mongoengine_marshmallow库的使用
文章目录
- mongoengine_marshmallow库的使用
- 一. 安装
- 二. marshmallow用法
- 1. 序列化(dump)
- 2.反序列化(load)
- 3. 更新操作(update)
- 4. 字段验证
- 5. Meta元类常用属性
- 6.常用字段类型
- 7.字段参数
在Django中有Serializer模块将Model字段序列化输出,Flask+sqlalchemy也可以解决关系型数据库的ORM序列化,那么如果用Flask+MongoEngine该如何选择呢
在搜索了许久之后, 找到了marshmallow库, 它本身不是针对ORM的,包装之后可以为mongoengine所用,达到最基本的功能序列化,反序列化,字段验证
一. 安装
# requirements.txt
Flask==1.0.2
flask-mongoengine==0.9.5
marshmallow_mongoengine
marshmallow==2.13.6
执行
pip install -r requirements.txt
二. marshmallow用法
dump - 序列化
load - 反序列化
update - 更新
validate - 字段验证, 可自定义
写个模型和序列化类
from marshmallow_mongoengine import ModelSchema, fields
# model
class User(db.Document):
name = db.StringField()
age = db.IntField()
# serializer
class UserSchema(ModelSchema):
name = fields.String()
age = fields.Int()
class Meta:
model = User
1. 序列化(dump)
>>> a = User(name="我是第一个").save()
>>> a
<User: User object>
>>> dump_data = UserSchema().dump(a)
>>> dump_data
MarshalResult(data={'id': '5cda5e43fe985e28c8e0c3b6', 'name': '我是第一个'}, errors={})
# 使用dump_data.data就可以获取到序列化后的值
可以看到,序列化后的值缺少了age
字段, 因为age字段没有值,那么要怎么返回age字段呢?
只需要在UserSchema
类下的Meta元类添加一条属性model_skip_values = ()
# UserSchema改为
class UserSchema(ModelSchema):
name = fields.String()
age = fields.Int()
class Meta:
model_skip_values = ()
model = User
再来看结果
>>> UserSchema().dump(a)
MarshalResult(data={'id': '5cda5e43fe985e28c8e0c3b6', 'name': '我是第一个', 'age': None}, errors={})
2.反序列化(load)
data = {"name":"哈哈", "age":11}
load_data = UserSchema().load(data)
>>> UnmarshalResult(data=<User: User object>, errors={})
3. 更新操作(update)
第一次尝试
处理报错
检查发现安装的marshmallow版本为最新的3.0+,在issue中找到了解决方案,安装2.13.6版本的marshmallow
第二次尝试
只修改了status
字段,可以看出这样并没有什么变化,因为没有做保存操作
第三次尝试
结果检测
update方法测试成功
4. 字段验证
>>> data = {"name": 123}
>>> schema = UserSchema()
>>> schema.validate(data)
{'name': ['Not a valid string.']}
自定义逻辑
class UserSchema(ModelSchema):
...
def validate(self, data, *args, **kwargs):
# 兼容前端age传null
if 'age' in data and data['age'] is None:
data['age'] = ''
return super().validate(data, *args, **kwargs)
5. Meta元类常用属性
class Meta:
model = User # 指定model
model_skip_values = () # 指定不展示的字段值
exclude = ("id",) # 排除字段
fields = ("name", "age") # 展示字段,不写该属性默认为model所有字段
6.常用字段类型
from marshmallow_mongoengine import ModelSchema, fields
# serializer
class UserSchema(ModelSchema):
name = fields.String() # 字符
age = fields.Int() # int型
is_admin = fields.Boolean() # 布尔类型
book = fields.Nested(BookSchema, many=True) # 引用型,many=True则为list
create_by = fields.Function(lambda obj: obj.create_by.name) # 自定义函数值
family = fields.Method("get_family") # 指定方法
def get_family(self, obj):
# 下面的只是个示例,意思是你可以通过自定义方法返回值给该字段
return FamilySchema(fields=("nickname", "id")).dump(obj.family, many=True).data
7.字段参数
- required:必选,缺省会触发validate校验返回错误
xx is required fields
- load_only: 仅反序列化时使用, 避免同一个序列化类使用报错
- dump_only: 仅序列化时使用
- attribute: 将数据库字段以你指定的名称展示
_id = fields.String(attribute="id")
- default: 序列化时值不存在默认展示
- format: 格式化输出
create_at = fields.DateTime(format='%Y-%m-%d %H:%M:%S')
参考文档: