Reputation: 18929
I have a form which takes a start date and end date as input.I need to set the valid range but this is dependent on another field, site. Like so:
class GraphForm(forms.Form):
site = forms.ChoiceField(choices=SITE_CHOICES, label=ugettext_lazy('Site'),
widget=forms.Select(attrs={"onChange":'filterField()'})
)
startdate = forms.DateField(
label=ugettext_lazy('Start Date'),
validators=[MaxValueValidator(maxdate)],
)
enddate = forms.DateField(
label=ugettext_lazy('End Date'),
validators=[MaxValueValidator(maxdate)],
)
...
But I can get a value for maxdate
only when a site has been selected:
getdate = Reports.objects.filter(site=site_name).values('recorded_on').order_by('-recorded_on')[:1]
maxdate = getdate[0]['recorded_on']
My question is how can I achieve this functionality - that I get the site input and then generate my maxdate value before the form can validate.
Any help much appreciated.
Upvotes: 2
Views: 4958
Reputation: 11
You can write a dynamic validation class, i.e. a class that does not take a constant but a function that will be called during validation.
from django.core.validators import MaxValueValidator
from django.core.exceptions import ValidationError
class DynamicMaxValueValidator(MaxValueValidator):
def __call__(self, value):
cleaned = self.clean(value)
params = {'limit_value': self.limit_value(), 'show_value': cleaned}
if self.compare(cleaned, self.limit_value()):
raise ValidationError(
self.message % params,
code=self.code,
params=params,
)
def maxdate():
getdate = Reports.objects.filter(site=site_name).values('recorded_on').order_by('-recorded_on')[:1]
return getdate[0]['recorded_on']
class GraphForm(forms.Form):
site = forms.ChoiceField(choices=SITE_CHOICES, label=ugettext_lazy('Site'),
widget=forms.Select(attrs={"onChange":'filterField()'})
)
startdate = forms.DateField(
label=ugettext_lazy('Start Date'),
validators=[DynamicMaxValueValidator(maxdate)],
)
enddate = forms.DateField(
label=ugettext_lazy('End Date'),
validators=[DynamicMaxValueValidator(maxdate)],
)
...
Notice that you must not call the function during initialization (no paranthesis behind maxdate when creating the DynamicMaxValueValidator)
Upvotes: 1
Reputation: 308899
You can't do this in the field definitions, as each field is validated separately. However, you could write a custom clean method for your form which checks start date and end date for you.
Upvotes: 2