天天看點

marshmallow之自定義Field

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

複制