20đź‘Ť
You could try writing a function which 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
You could then create the validator you actually want 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 the correction @user2577922)
PS I’ve not tested this, but hopefully you get the idea – write a function which takes the
two dates you want to have as the bounds of your range, and which returns a function which
checks that a date it is passed is in the range.
17đź‘Ť
I would suggest to take a look at django.core.validators to see how Django uses the Regex validator, and extends it to use for different type 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
Simply pass your parameters to the validator in
validators=[MyValidator(params)]
Haven’t tested but I don’t see any reason why it wouldn’t work.
EDIT:
Had a chance to test it and it works.
4đź‘Ť
Based on amertkara’s solution, I pass user’s email address to the form, then I validate the user input agaist 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đź‘Ť
You can build a validator, taking as example the builtin validators, dont forget use de deconstructible decorator on the class.
from django.utils.deconstruct import 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}"'
)
- ValueError: "needs to have a value for field "id" before this many-to-many relationship can be used"
- From django.db import models, migrations ImportError: cannot import name migrations
- What's the difference between override_settings and modify_settings in Django?
- @csrf_exempt stopped working in Django 1.4
- Is there any way to use GUIDs in django?
2đź‘Ť
You can try using a lambda expression (Never tried it myself, so I don’t know if it will work or not):
forms.DateField(validators=[lambda value: validate_range_of_data(value, "01/06/2012", "31/03/2012")])
Of course, you have to ask yourself if that’s “nicer” than just validating in the field’s clean method.
- Converting a django ValuesQuerySet to a json object
- In Django how do I notify a parent when a child is saved in a foreign key relationship?
1đź‘Ť
in the new Django 4.2, this is the recommended way to do it:
in models.py or validators.py which is imported to models:
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
class max_length_validator(object):
def __init__(self, length): # can add any params here
if length is not None:
self.length = length
def __call__(self, value) -> Any:
if len(str(value)) > self.length:
raise ValidationError(
_("%(value)s length is too long."),
params={"value": value},
)
and in the field itself:
field = models.IntegerField(validators=[max_length_validator(length=4)])
this is exactly how the django developer team coded the regex validator for example 🙂
- Enable PK based filtering in Django Graphene Relay while retaining Global IDs
- How to create new resource with foreign key in TastyPie
- Can I create model in Django without automatic ID?