将字段名传入基于函数的校验器

后端开发 2026-07-08

验证错误信息,realestate/locale/sr/LC_MESSAGES/django.po

msgid "field.date"
msgstr "Polje {field} mora biti ispravan datum."
msgid "field.string"
msgstr "Polje {field} mora biti string."

带有验证器的表单,realestate\auth2\forms.py

class RegisterForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ["email", "password1", "password2", "phone", "first_name", "last_name", "birth_date"]
        widgets = {"birth_date": forms.DateInput(attrs={"type": "date"})}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # 2 Input validation & sanitization
        self.fields["email"].validators = [EmailValidator(message=_("email.email").format(field=_("email")))]
        self.fields["email"].validators = [validate_string]
        self.fields["phone"].validators = [RegexValidator(regex=r"^\+381 \d{2} \d{6,7}$", message=_("phone.regex"))]
        self.fields["first_name"].validators = [AlphaValidator(message=_("field.alpha").format(field=_("first_name")))]
        self.fields["last_name"].validators = [AlphaValidator(message=_("field.alpha").format(field=_("last_name")))]
        self.fields["birth_date"].validators = [validate_date, validate_adult]

用于验证字段是字符串或日期的验证器,realestate\realestate\validators.py

def validate_string(value):
    if type(value) is not date:
        raise ValidationError(_("field.string").format(field=field), code="invalid")


def validate_date(value):
    if type(value) is not date:
        raise ValidationError(_("field.date").format(field=field), code="invalid")

如何把字段名传给验证器?

解决方案

我没法测试,但最简单的做法可能是使用 lambda 来传递额外的参数 field

原始函数需要一个额外的参数

def validate_string(value, field):  # <-- field
    # if not isinstance(value, str):
    if type(value) is not str:
        raise ValidationError(_("field.string").format(field=field), code="invalid")

然后

self.fields["email"].validators = [lambda value: validate_string(value, "email")]

validators 的文档中,你可以找到源码的链接,例如 EmailValidator,你也可以看到如何使用类来设置额外的参数,以及如何使用 __call__ 来执行验证。

可能是这样的(带有 self.field

class MyStringValidator:

    def __init__(self, field):
        self.field = field

    def __call__(self, value):
        # if not isinstance(value, str):
        if type(value) is not str:
            raise ValidationError(_("field.string").format(field=self.field), code="invalid")

self.fields["email"].validators = [MyStringValidator("email")]
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章