marshmallow之自定義Field

有三種方式建立自定義的field。ide

建立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中某個方法的返回值,該方法必須接收一個要進行序列化的對象的參數objui

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參數:code

class UserSchema(Schema):
    name = fields.String()
    email = fields.String()
    created_at = fields.DateTime()
    uppername = fields.Function(lambda obj: obj.name.upper())

Method和Function的反序列化

fields.Methodfields.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能夠訪問此字典。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.'}
    )
相關文章
相關標籤/搜索