Is it possible to have validators with parameters?

I can not find the answer to this question. I would like to create validators in Django with parameters like:

In the forms.py file:

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

In validators.py file:

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

Now I can do it with a clean method or make a custom field, but I think it would be better to do it with a validator. Is it possible?

Thanks in advance

+6
source share
4 answers

You can try writing a function that returns a function.

 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 

Then you can create the validator you need by calling this function:

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

(thanks for fixing @ user2577922 )

PS I have not tested this, but I hope you get an idea - write a function that takes two dates that you want to have as the boundaries of your range, and that returns a function that checks that the date in which it is passed is in range.

+6
source

I would suggest looking at django.core.validators to find out how Django uses the Regex validator and extends it for use for different types of fields.

 class MyValidator (object): def __init__(self, params): pass # Init the instance variables here def __call__(self, value): pass # Actual validation logic comes here 

Just pass your parameters to the validator in

 validators=[MyValidator(params)] 

Not tested, but I see no reason why this will not work.

EDIT:

There was an opportunity to check it, and it works.

+5
source

Based on the amertkara solution, I pass the user's email address into the form, then I check how the user enters his own email address.

 # 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 
+3
source

You can try using the lambda expression (never tried this on your own, so I don't know if this will work or not):

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

Of course, you should ask yourself if this is "more enjoyable" than just checking in the field cleaning method.

0
source

Source: https://habr.com/ru/post/922068/


All Articles