有三种方式建立自定义的field。ide
建立继承自marshmallow.fields.Field
类的子类并实现_serialize
和/或_deserialize
方法:函数
from marshmallow import fields, Schema class Titlecased(fields.Field): def _serialize(self, value, attr, obj): if value is None: return '' return value.title() class UserSchema(Schema): name = fields.String() email = fields.String() created_at = fields.DateTime() titlename = TitleCased(attribute="name")
fields.Method
将序列化schema中某个方法的返回值,该方法必须接收一个要进行序列化的对象的参数obj
:ui
class UserSchema(Schema): name = fields.String() email = fields.String() created_at = fields.DateTime() since_created = fields.Method("get_days_since_created") def get_days_since_created(self, obj): return dt.datetime.now().day - obj.created_at.day
fields.Function
将序列化传递给它的函数的返回值,也接收一个obj
参数:code
class UserSchema(Schema): name = fields.String() email = fields.String() created_at = fields.DateTime() uppername = fields.Function(lambda obj: obj.name.upper())
fields.Method
和fields.Function
都接收一个可选的deserialize
参数,该参数定义了如何反序列化字段:对象
class UserSchema(Schema): # Method接收字符串类型的方法名, Function接收callable对象 balance = fields.Method('get_balance', deserialize='load_balance') def get_balance(self, obj): return obj.income - obj.debt def load_balance(self, value): return float(value) schema = UserSchema() result = schema.load({'balance': '100.00'}) result.data['balance'] # => 100.0
Function和Method序列化时可能须要相关环境信息。能够为schema设置context
属性(dict对象),Function和Method能够访问此字典。blog
下面的例子判断某个User对象是不是某个Blog对象的做者,以及Blog的title属性是否出现bicycle
单词:继承
class UserSchema(Schema): name = fields.String() # Function fields optionally receive context argument is_author = fields.Function(lambda user, context: user == context['blog'].author) likes_bikes = fields.Method('writes_about_bikes') # Method fields also optionally receive context argument def writes_about_bikes(self, user): return 'bicycle' in self.context['blog'].title.lower() schema = UserSchema() user = User('Freddie Mercury', 'fred@queen.com') blog = Blog('Bicycle Blog', author=user) schema.context = {'blog': blog} data, errors = schema.dump(user) data['is_author'] # => True data['likes_bikes'] # => True
字段验证产生的错误信息能够在类级别或实例级别配置。字符串
在类级别时,default_error_messages
能够定义为错误码和错误信息的字典映射:get
from marshmallow import fields class MyDate(fields.Date): default_error_messages = { '400001': 'Please provide a valid date.', }
在Field类实例化时,给error_messages
参数传参(dict对象):it
from marshmallow import Schema, fields class UserSchema(Schema): name = fields.Str( required=True, error_messages={'required': 'Please provide a name.'} )