前言
cerberus 翻译为地狱犬,是地狱的看门狗,比喻做数据的校验者。 这个库是专门用来校验做数据校验。 可以通过定义一个 schema 文件来快速校验数据是否复合 schema。
Github 地址 官方说明文档
cerberus 介绍 cerberus 基本用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from cerberus import Validatorschema = { "name" : {"type" : "string" }, "member" : { "type" : "dict" , "require_all" : True , "schema" : {"address" : {"type" : "string" }}, }, } v = Validator(schema) document = {"name" : "john doe" , "member" : {}} result = v.validate(document) print (result) print (v.errors)
主要用法就是定义一个规范。 cerberus 会根据这个规范对数据进行校验。 这其中的规则既可以根据官方文档添加,也可以继承 Validator 实现自定义的规则。
cerberus 嵌套检查 1 2 3 4 5 6 7 8 from cerberus import schema_registryschema_registry.add("non-system user" , {"uid" : {"min" : 1000 , "max" : 0xFFFF }}) schema = { "sender" : {"schema" : "non-system user" , "allow_unknown" : True }, "receiver" : {"schema" : "non-system user" , "allow_unknown" : True }, }
导入 schema_registry 添加到里面的 schema 可以被别的地方复用。 别的 schema 只要输入相应的字符串就可以复用 schema 或者也可以通过接入字典变量的方式来复用 schema
cerberus 自定义检查功能
扩展检查规则可以通过继承 Validator
来实现,非常简单方便。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from cerberus import Validatorclass MyValidator (Validator ): def _validate_is_odd (self, constraint, field, value ): """ Test the oddity of a value. The rule's arguments are validated against this schema: {'type': 'boolean'} """ if constraint is True and not bool (value & 1 ): self._error(field, "Must be an odd number" ) schema = {'amount' : {'is odd' : True , 'type' : 'integer' }} v = MyValidator(schema) v.validate({'amount' : 10 })
结合 marshmallow 使用
使用 cerberus 的 schema 可以让校验规则统一到一个地方进行配置。 配置更加清晰,查找也比较方便。 相较于使用 attrs
或者 marshmallow
提供校验功能。 cerberus 可以更加清晰地配置和修改。
我上一篇文章介绍了使用 marshmallow
可以很方便地对数据进行序列化。 同时它也可以对每一个 field 编写函数进行数据校验,但是如果使用 嵌套 Schema 的话 这些校验方法东一块西一块,配置和修改都非常繁琐。 这个使用可以结合 marshmallow
的 validates_schema
装饰器通过函数调用 cerberus 进行数据校验。 marshmallow 文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 from marshmallow import Schema, fields, validates_schema, ValidationErrorfrom cerberus import Validatorschema = { "field_a" : { "required" : True , "type" : "integer" , "min" : 0 , "max" : 5 , } } validator = Validator(schema) class MySchema (Schema ): field_a = fields.Int(required=True ) field_b = fields.Int(required=True ) @validates_schema(pass_original=True ) def validate_schema (self, data, original_data ): if not validator.validate(original_data): raise ValidationError(validator.errors) schema = MySchema() document = { "field_a" : -1 , "field_b" : -1 , } res, err = schema.load(document) print (err)
这样就可以实现反序列化数据的同时进行数据校验。
总结
cerberus 其实也可以做数据的 coerce ,实现一定程度的序列化功能。 不过如果需要嵌套的话,还是用 marshmallow 进行处理比较方便。 而且 marshmallow 嵌套调用也可以配合着 cerberus 顺便进行数据校验。