I've been doing things like this in the clean method:
if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
raise forms.ValidationError('The type and organization do not match.')
if self.cleaned_data['start'] > self.cleaned_data['end']:
raise forms.ValidationError('The start date cannot be later than the end date.')
But then that means that the form can only raise one of these errors at a time. Is there a way for the form to raise both of these errors?
EDIT #1: Any solutions for the above are great, but would love something that would also work in a scenario like:
if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
raise forms.ValidationError('The type and organization do not match.')
if self.cleaned_data['start'] > self.cleaned_data['end']:
raise forms.ValidationError('The start date cannot be later than the end date.')
super(FooAddForm, self).clean()
Where FooAddForm is a ModelForm and has unique constraints that might also cause errors. If anyone knows of something like that, that would be great...
From the docs:
from django.forms.util import ErrorList
def clean(self):
if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
msg = 'The type and organization do not match.'
self._errors['type'] = ErrorList([msg])
del self.cleaned_data['type']
if self.cleaned_data['start'] > self.cleaned_data['end']:
msg = 'The start date cannot be later than the end date.'
self._errors['start'] = ErrorList([msg])
del self.cleaned_data['start']
return self.cleaned_data
errors = []
if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
errors.append('The type and organization do not match.')
if self.cleaned_data['start'] > self.cleaned_data['end']:
errors.append('The start date cannot be later than the end date.')
if errors:
raise forms.ValidationError(errors)
If you'd prefer that the error messages be attached to the form rather than to specific fields, you can use the key "__all__
" like this:
msg = 'The type and organization do not match.'
self._errors['__all__'] = ErrorList([msg])
Also, as the Django docs explain: "if you want to add a new error to a particular field, you should check whether the key already exists in self._errors
or not. If not, create a new entry for the given key, holding an empty ErrorList
instance. In either case, you can then append your error message to the list for the field name in question and it will be displayed when the form is displayed."
Although its old post, if you want less code you can use add_error()
method to add error messages. I am extending the @kemar's answer to show the used case:
add_error()
automatically removes the field from cleaned_data dictionary, you dont have to delete it manually.
Also you dont have to import anything to use this.
def clean(self):
if self.cleaned_data['type'].organized_by != self.cleaned_data['organized_by']:
msg = 'The type and organization do not match.'
self.add_error('type', msg)
if self.cleaned_data['start'] > self.cleaned_data['end']:
msg = 'The start date cannot be later than the end date.'
self.add_error('start', msg)
return self.cleaned_data
来源:https://stackoverflow.com/questions/2117048/django-overriding-the-clean-method-in-forms-question-about-raising-errors