marshmallowのカスタムフィールド
3576 ワード
カスタムfieldを作成するには、3つの方法があります.
Fieldクラスのサブクラスの作成
Method Fields
Function Fields
MethodとFunctionの逆シーケンス化
MethodとFunctionのコンテキストの追加
FunctionとMethodのシーケンス化には、関連する環境情報が必要になる場合があります.この辞書にはschemaに
次の例では、あるUserオブジェクトがBlogオブジェクトの作成者であるかどうか、およびBlogのtitle属性が
カスタムエラー情報
フィールド検証によって生成されたエラー情報は、クラスレベルまたはインスタンスレベルで構成できます.
クラスレベルでは、
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.'}
)