有三种方式创建自定义的 field。
创建 Field 类的子类
创建继承自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")
Method Fields
fields.Method将序列化 schema 中某个方法的返回值,该方法必须接收一个要进行序列化的对象的参数obj:
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
Function Fields
fields.Function将序列化传递给它的函数的返回值,也接收一个obj参数:
class UserSchema(Schema):
name = fields.String()
email = fields.String()
created_at = fields.DateTime()
uppername = fields.Function(lambda obj: obj.name.upper())
Method 和 Function 的反序列化
fields.Method和fields.Function都接收一个可选的deserialize参数,该参数定义了如何反序列化字段:
class UserSchema(Schema):
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']
为 Method 和 Function 添加上下文
Function 和 Method 序列化时可能需要相关环境信息。可以为 schema 设置context属性 (dict 对象),Function 和 Method 可以访问此字典。
下面的例子判断某个 User 对象是否是某个 Blog 对象的作者,以及 Blog 的 title 属性是否出现bicycle单词:
class UserSchema(Schema):
name = fields.String()
is_author = fields.Function(lambda user, context: user == context['blog'].author)
likes_bikes = fields.Method('writes_about_bikes')
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']
data['likes_bikes']
自定义错误信息
字段验证产生的错误信息可以在类级别或实例级别配置。
在类级别时,default_error_messages可以定义为错误码和错误信息的字典映射:
from marshmallow import fields
class MyDate(fields.Date):
default_error_messages = {
'400001': 'Please provide a valid date.',
}
在 Field 类实例化时,给error_messages参数传参 (dict 对象):
from marshmallow import Schema, fields
class UserSchema(Schema):
name = fields.Str(
required=True,
error_messages={'required': 'Please provide a name.'}
)