有三種方式建立自定義的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):
# 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
複制
為Method和Function添加上下文
Function和Method序列化時可能需要相關環境資訊。可以為schema設定
context
屬性(dict對象),Function和Method可以通路此字典。
下面的例子判斷某個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', '[email protected]')
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
可以定義為錯誤碼和錯誤資訊的字典映射:
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.'}
)
複制