0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonライブラリの「Cerberus」を使ってカスタムバリデーションを作成する

Last updated at Posted at 2023-11-15

初めに

Cerberusは、データのバリデーションに使用されるPythonライブラリで、柔軟なルール設定とエラーハンドリング機能を提供します。
以下のコードは、CerberusのValidatorクラスを継承するCustomValidatorクラスの実装方法を示しています。

使用例

カスタムバリデーションクラスの定義
class CustomValidator(Validator):

    def __init__(self, schema: dict):
        super().__init__()
        self.schema = schema
        self.error_handler = CustomErrorHandler()

    def get_error_message(self) -> str:
        # エラーメッセージをカンマ区切りの文字列に成形
        message_list = []
        for messages in self.errors.values():
            for message in messages:
                message_list.append(message)

        return ", ".join(message_list)

    def _validate_str_length(self, length, field, value):
        if length is not None and len(value) != length:
            self._error(field, f"{field}{length}文字でなければなりません")

    def _validate_numeric_str(self, constraint, field, value):
        if not constraint:
            return

        if type(value) is not str or not re.match("^[0-9]*$", value):
            self._error(field, f"{field}は数の文字列でなければなりません")


class CustomErrorHandler(BasicErrorHandler):
    """ BasicErrorHandler.message を上書きして日本語化 """

    def __init__(self, tree=None):
        super(CustomErrorHandler, self).__init__(tree)
        messages = super().messages.copy()
        self.messages = messages | {
            0x02: "{field}は必須項目です",
            0x22: "{field}は空値であってはなりません",
            0x23: "{field}はNullであってはなりません",
            ....
        }

CustomValidatorのコンストラクタは、引数として受け取ったスキーマを基に初期化されます。

また、エラーメッセージのカスタマイズのためにBasicErrorHandlerを継承した、CustomErrorHandlerクラスも初期化されます。
このCustomErrorHandlerは、エラーの種類に応じて日本語のエラーメッセージを返すために、エラーキーと対応するメッセージをmessages属性に格納します。

schema
schema = {
    "page": {
        "str_length": 8,
        "numeric_str": True,
    }

カスタムバリデーションルールは、_validate_str_length_validate_numeric_strメソッドを通して実装されます。

これらはスキーマ定義において、それぞれstr_lengthnumeric_strキーに対応する値を設定することで適用されます。
例えば、str_lengthに8を設定すると、対象のフィールドが8文字であることを確認します。

バリデーション
def validate(self, schema: dict, type: str):
        v = CustomValidator(schema)
        if not v.validate(params):
                print(v.get_error_message())

バリデーションプロセスでは、CustomValidatorにスキーマを渡してインスタンス化し、.validateメソッドで対象のデータを検証します。

もしバリデーションが失敗した場合、get_error_messageメソッドを用いてエラーメッセージを取得し出力することができます。
このプロセスにおいて、params(検証するデータ)は.validateメソッドに渡される必要があります。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?