Django - How to specify which field a validation fails on?
OK, I figured it out from this answer.
You have to do something like this:
class Dog(models.Model):
bark_volume = models.DecimalField(...
unladen_speed = models.DecimalField(...
def clean_fields(self):
if self.bark_volume < 5:
raise ValidationError({'bark_volume': ["Must be louder!",]})
class Dog(models.Model):
bark_volume = models.DecimalField(...
unladen_speed = models.DecimalField(...
def clean(self):
if self.bark_volume < 5:
if not self._errors.has_key('bark_volume'):
from django.forms.util import ErrorList
self._errors['bark_volume'] = ErrorList()
self._errors['bark_volume'].append('must be louder!')
That works on forms, at least. Never tried it on the model itself, but the methodology should be the same. However, from the Django docs:
When you use a ModelForm, the call to is_valid() will perform these validation steps for all the fields that are included on the form. (See the ModelForm documentation for more information.) You should only need to call a model’s full_clean() method if you plan to handle validation errors yourself, or if you have excluded fields from the ModelForm that require validation.
And...
Note that full_clean() will not be called automatically when you call your model’s save() method, nor as a result of ModelForm validation. You’ll need to call it manually when you want to run model validation outside of a ModelForm.
So, basically, unless you have a really good reason to do field cleaning on the model, you should do it on the form instead. The code for that would look like:
class DogForm(forms.ModelForm):
def clean(self):
bark_volume = self.cleaned_data.get('bark_volume')
if bark_volume < 5:
if not self._errors.has_key('bark_volume'):
from django.forms.util import ErrorList
self._errors['bark_volume'] = ErrorList()
self._errors['bark_volume'].append('must be louder!')
return self.cleaned_data
And that will work, for sure.