I have an Event model that I'd like to place the following validation rule on, in a custom def clean(self):
method on the Model:
def clean(self):
from django.core.exceptions import ValidationError
if self.end_date is not None and self.start_date is not None:
if self.end_date < self.start_date:
raise ValidationError('Event end date should not occur before start date.')
Which works fine, except that I'd like to highlight the self.end_date
field in the admin UI, by somehow nominating it as the field that has errors. Otherwise I only get the error message that occurs at the top of the change form.
The docs
explain how to do this at the bottom.
provided example:
class ContactForm(forms.Form):
# Everything as before.
...
def clean(self):
cleaned_data = self.cleaned_data
cc_myself = cleaned_data.get("cc_myself")
subject = cleaned_data.get("subject")
if cc_myself and subject and "help" not in subject:
# We know these are not in self._errors now (see discussion
# below).
msg = u"Must put 'help' in subject when cc'ing yourself."
self._errors["cc_myself"] = self.error_class([msg])
self._errors["subject"] = self.error_class([msg])
# These fields are no longer valid. Remove them from the
# cleaned data.
del cleaned_data["cc_myself"]
del cleaned_data["subject"]
# Always return the full collection of cleaned data.
return cleaned_data
for your code:
class ModelForm(forms.ModelForm):
# ...
def clean(self):
cleaned_data = self.cleaned_data
end_date = cleaned_data.get('end_date')
start_date = cleaned_data.get('start_date')
if end_date and start_date:
if end_date < start_date:
msg = 'Event end date should not occur before start date.'
self._errors['end_date'] = self.error_class([msg])
del cleaned_data['end_date']
return cleaned_data
From Django 1.7 you can directly add error to the particular field by using add_error
method. Django docs
form.add_error('field_name', 'error_msg or ValidationError instance')
If the field_name
is None
the error will be added to non_field_errors
.
def clean(self):
cleaned_data = self.cleaned_data
end_date = cleaned_data.get('end_date')
start_date = cleaned_data.get('start_date')
if end_date and start_date:
if end_date < start_date:
self.add_error('end_date', 'Event end date should not occur before start date.')
# You can use ValidationError as well
# self.add_error('end_date', form.ValidationError('Event end date should not occur before start date.'))
return cleaned_data