読者です 読者をやめる 読者になる 読者になる

marshmallow-formのvalidation部分の機能を修正しました。

marshmallow-formのvalidation部分の機能を修正しました。

昨日時点のままでも以下の様なコードは動いていました*1

from marshmallo.validate import Length


class AuthenticationForm(mf.Form):
    name = mf.String()
    password = mf.String(Length(5))
    password_confirm = mf.String()


@AuthenticationForm.Schema.validator
def same(schema, data):
    return data["password"] == data["password_confirm"]


input_data = {"name": "foo", "password": "*", "password_confirm": "+"}
form = AuthenticationForm(input_data)
form.deserialize()

assert form.has_errors()
print(form.errors)
{'_schema': ["Schema validator same({'password_confirm': '+', 'password': '*', 'name': 'foo'}) is False"],
'password': ['Too short! 5.']}

もちろんvalidationErrorを送出する際にfieldを指定してあげれば、任意のメッセージを渡すことができます。

@AuthenticationForm.Schema.validator
def same(schema, data):
    if data["password"] != data["password_confirm"]:
        raise ValidationError("not same!", "password")

# 失敗時には以下のような形に
# {"password": ["not same!"]}

他のフォームライブラリとの兼ね合いから、クラス定義の内部でvalidationを登録した方が良いだろうということで以下の様にも書けるようにしました。

from marshmallow.validate import Length


class MLength(Length):
    message_min = 'Too short! {min}.'
    message_max = 'Too long! {max}.'


class AuthenticationForm(mf.Form):
    name = mf.String()
    password = mf.String(validate=MLength(5))
    password_confirm = mf.String()

    @mf.Form.validator
    def same(schema, data):
        if data["password"] != data["password_confirm"]:
            raise ValidationError("not same!", "password")

困っていること

  • marshmallowにはi18n対応が無い。
  • validatorを実行する方法を変える方法が無い。

marshmallowにはi18n対応が無い

これは必要といえば必要ですが。基本的には不要な機能かなと思っています。 marshmallow.validateに幾つかのvalidate用の関数・オブジェクトがあるのですが。一応はこれをコピペしたり上のMLengthのように一部メッセージを変更することでしのげるのではないかなーと思っています。

validatorを実行する方法を変える方法が無い

これどうしようか考え中。

*1:marshmallowすごい。