Django model's clean method multiple error
Question:
I have been playing around with my test project
I have this clean method in my model
class SomeModel(models.Model):
f1 = models.IntegerField()
f2 = models.IntegerField()
def clean(self):
if self.f1 > self.f2:
raise ValidationError({'f1': ['Should be greater than f1',]})
if self.f2 == 100:
raise ValidationError({'f2': ['That's too much',]})
I don’t really know how to raise both errors and show it in the admin page because even if the two if
is True
, only the first if
error is shown(obviously) how do I show both errors?
Answers:
You could build a dict
of errors and raise a ValidationError when you are done (if necessary):
class SomeModel(models.Model):
f1 = models.IntegerField()
f2 = models.IntegerField()
def clean(self):
error_dict = {}
if self.f1 > self.f2:
error_dict['f1'] = ValidationError("Should be greater than f1") # this should probably belong to f2 as well
if self.f2 == 100:
error_dict['f2'] = ValidationError("That's too much")
if error_dict:
raise ValidationError(error_dict)
I would expand the accepted answer by setting a classmethod like this:
@classmethod
def add_error(cls, errordict, error):
for key, value in error.items():
if key in errordict:
if isinstance(errordict[key], str) or isinstance(errordict[key], ValidationError):
errordict.update({key: [errordict[key], value]})
elif isinstance(errordict[key], list):
errordict[key].append(value)
else:
errordict.update(error)
return errordict
That way, if a key already exists in your error dict, it will be casted in a list. That way, all the errors will be raised, even if there are multiple errors per field.
adderror(error_dict, {'field', 'error message'})
I have been playing around with my test project
I have this clean method in my model
class SomeModel(models.Model):
f1 = models.IntegerField()
f2 = models.IntegerField()
def clean(self):
if self.f1 > self.f2:
raise ValidationError({'f1': ['Should be greater than f1',]})
if self.f2 == 100:
raise ValidationError({'f2': ['That's too much',]})
I don’t really know how to raise both errors and show it in the admin page because even if the two if
is True
, only the first if
error is shown(obviously) how do I show both errors?
You could build a dict
of errors and raise a ValidationError when you are done (if necessary):
class SomeModel(models.Model):
f1 = models.IntegerField()
f2 = models.IntegerField()
def clean(self):
error_dict = {}
if self.f1 > self.f2:
error_dict['f1'] = ValidationError("Should be greater than f1") # this should probably belong to f2 as well
if self.f2 == 100:
error_dict['f2'] = ValidationError("That's too much")
if error_dict:
raise ValidationError(error_dict)
I would expand the accepted answer by setting a classmethod like this:
@classmethod
def add_error(cls, errordict, error):
for key, value in error.items():
if key in errordict:
if isinstance(errordict[key], str) or isinstance(errordict[key], ValidationError):
errordict.update({key: [errordict[key], value]})
elif isinstance(errordict[key], list):
errordict[key].append(value)
else:
errordict.update(error)
return errordict
That way, if a key already exists in your error dict, it will be casted in a list. That way, all the errors will be raised, even if there are multiple errors per field.
adderror(error_dict, {'field', 'error message'})