Reputation: 35
I have the following form fields on a ModelForm
subclass:
forms.py
class ProjectUpdateForm(ModelForm):
start_date = DateField(...)
due_date = DateField(label="Due Date",
required=True,
widget=CustomDatePicker(),
validators=[validate_not_past])
def clean(self):
super().clean() # Problem: this isn't this raising a ValidationError...
start_date = self.cleaned_data.get('start_date')
due_date = self.cleaned_data.get('due_date')
if start_date > due_date: # ...instead getting a TypeError from this line!
raise ValidationError("Project Start Date cannot be after Project End Date")
validators.py
def validate_not_past(value):
today = datetime.date.today()
if value and value < today:
raise ValidationError('This date cannot be in the past.', code='invalid')
Anytime that I enter a date in the past, the applications throws a TypeError: '>' not supported between instances of 'datetime.date' and 'NoneType'
(see comments above for clarity).
After attempting to troubleshoot, the POST data comes in fine from the form. The problem occurs because run_validators()
is raising the ValidationError
triggered by the validate_not_past
, validator (above) as expected. However, rather than raising the ValidationError
, the self.cleaned_data
dictionary just doesn't get a due_date
key.
I can't figure out why I'm not getting a ValidationError
raised. I can't find code elsewhere that catches it.
Thanks in advance.
Upvotes: 0
Views: 47
Reputation: 1421
The clean_method
can ideally optionally return a dictionary (recommended) to return the cleaned_data
. If you do this and are doing inheritance in Forms, you'll not face any errors. Currently, your ProjectUpdateForm
is not utilizing it correctly to call the clean()
method on the super-class. Your code will be fixed if you call it correctly like this:
class ProjectUpdateForm(ModelForm):
start_date = DateField(...)
due_date = DateField(label="Due Date",
required=True,
widget=CustomDatePicker(),
validators=[validate_not_past])
def clean(self):
cleaned_data = super().clean()
start_date = cleaned_data.get('start_date')
due_date = cleaned_data.get('due_date')
if start_date and due_date and start_date > due_date:
raise ValidationError("Project Start Date cannot be after Project End Date")
return cleaned_data
Note here that I'm also checking start_date
and due_date
are not None
before doing the comparison between them. It wasn't evident from your code if the start_date
is also mandatory, so I added this additional check.
Finally, I'm also returning cleaned_data
which is optional but recommended, since then it enables this form to be inherited in other forms without any worries of correctly propagating errors from the super-class forms.
Upvotes: 0