15

我找不到有关此主题的任何相关答案。我想在 Django 中使用一些参数创建验证器,例如:

在 forms.py 文件中:

class DateForm(forms.Form):
    forms.DateField(
        validators=[validate_range_of_date(value,"01/06/2012","31/03/2013")]
        )

在 validators.py 文件中:

def validate_range_of_date(date_to_verify, min_date, max_date):
    ...

我现在可以通过 clean 方法或自定义字段来完成,但我认为通过验证器来完成会更好。是否可以?

提前致谢

4

5 回答 5

19

您可以尝试编写一个返回函数的函数。

def date_range_validator(min_date, max_date):
    def innerfn(date_to_test):
        if not (min_date <= date_to_test <= max_date):
            raise ValidationError(
                'Inappropriate date: %s is not between %s and %s' %
                (date_to_test, min_date, max_date)
                )
    return innerfn

然后你可以通过调用这个函数来创建你真正想要的验证器:

class DateForm(forms.Form):
    forms.DateField(
        validators=[
            date_range_validator(
                datetime.date(2012, 06, 01), datetime.date(2013, 03, 31)
                )
            ]
        )

(感谢@user2577922的更正)

PS我没有对此进行测试,但希望你明白 - 编写一个函数,它将你想要的两个日期作为你的范围的界限,并返回一个函数来检查它传递的日期是否在范围。

于 2012-08-03T21:38:20.037 回答
14

我建议看一下django.core.validators以了解 Django 如何使用 Regex 验证器,并将其扩展为用于不同类型的字段。

class MyValidator (object):
    def __init__(self, params):
        pass  #  Init the instance variables here

    def __call__(self, value):
        pass  # Actual validation logic comes here

只需将您的参数传递给验证器

validators=[MyValidator(params)]

还没有测试,但我看不出它为什么不起作用的任何原因。

编辑:

有机会测试它并且它有效。

于 2015-02-16T13:41:51.220 回答
4

基于 amertkara 的解决方案,我将用户的电子邮件地址传递给表单,然后验证用户输入与他自己的电子邮件地址是否相符。

# form
class new_user_form(forms.Form):
    def __init__(self, *args, **kwargs):
        own_mail = kwargs.pop('own_mail')
        super(new_user_form, self).__init__(*args, **kwargs)
        self.fields['email'] = forms.EmailField(
            label='',
            required=True,
            validators = [ not_own_mail(own_mail) ]
        )

# validator
class not_own_mail(object):
    def __init__(self, email):
        self.email = email

    def __call__(self, value):
       if value == self.email:
            raise ValidationError('It must be a different email address.')
       else:
           return value
于 2015-03-30T20:18:58.543 回答
2

您可以尝试使用 lambda 表达式(我自己从未尝试过,所以我不知道它是否有效):

forms.DateField(validators=[lambda value: validate_range_of_data(value, "01/06/2012", "31/03/2012")])

当然,您必须问自己这是否比仅在该领域的 clean 方法中验证“更好”。

于 2012-08-03T16:40:46.990 回答
2

您可以构建一个验证器,以内置验证器为例,不要忘记在类上使用 de deconstructible 装饰器。

@deconstructible
class ValidateStartsWith(object):
    def __init__(self, prefix: str):
        self.prefix = prefix

    def __call__(self, value: str):
        value = value.strip()
        if value.startswith(self.prefix):
            if value == self.prefix:
                raise ValidationError(
                    f'El nombre debe incluir el prefijo "{self.prefix}" y algo más'
                )
        else:
            raise ValidationError(
                f'La convención del nombre exige que empieze con el prefijo "{self.prefix}"'
            )
于 2021-05-05T19:46:38.917 回答