django.db.models.Field.validatorsの関数に引数を与えられるようにします。
例えば以下のようなバリデータにおいて、ハードコードされた数値 100
をモデルフィールド単位に指定できるようにします。
def equal_to_100(value): if value != 100: raise ValidationError(f'{value} is not equal to 100.') class MyModel(models.Model): foo = models.IntegerField(validators=[equal_to_100, ])
実行環境
- Django 2.2
カスタムバリデータクラスの実装
RegexValidatorのようなクラスベースのカスタムバリデータを作成します。
__init__
で任意のバリデータとキーワード引数を受け付け、 __call__
でバリデーションします。
migrationフレームワークでシリアライズできるように、
@deconstructible
の付与と __eq__
の実装が必要です(詳細はこちら)。
from django.utils.deconstruct import deconstructible @deconstructible class BaseValidator: def __init__(self, validator, **kwargs): self.validator = validator self.kwargs = kwargs def __call__(self, value): self.validator(value, **self.kwargs) def __eq__(self, other): return ( isinstance(other, self.__class__) and self.validator == other.validator and self.kwargs == other.kwargs )
バリデータに引数を追加
これでバリデータの指定を validators=[BaseValidator(your_validator, param1=..., param2=...)]
といった具合に変更することで、既存の関数に任意のキーワード引数を与えられるようになります。
from django.core.exceptions import ValidationError def equal_to(value, expected=None): if value != expected: raise ValidationError(f'{value} is not equal to {expected}.') class MyModel(models.Model): foo = models.IntegerField(validators=[BaseValidator(equal_to, expected=100)])