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)
Answered By: user2390182

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'})
Answered By: R. Steigmeier
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.