有三種方式建立自定義的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.'} )