Let's assume I have a Django model:
class MyDjangoModel(models.Model):
name = models.CharField(max_length=200)
attribute = models.IntegerField()
class CustomValidationError(ValidationError):
pass
def clean(self):
if self.attribute < 1:
raise CustomValidationError("Attribute should be > 1!")
if len(self.name) > 20:
raise ValidationError("Name too long!")
I would like to create model instance and validate it:
inst = MyDjangoModel(name="Foo", attribute=0)
try:
inst.full_clean()
except CustomValidationError:
print("Hello!")
except ValidationError:
print("Bye!")
But the code above will never print "Hello!"
because full_clean
method is raising only ValidationError
.
Can anyone suggest, how to call full_clean
and check if ValidationError
subclass exception was raised?
The full_clean
method collects all the errors raised on several phases.
You can check how it's calling your clean
method here: https://github.com/django/django/blob/master/django/db/models/base.py#L1150
Luckily, the original exceptions are preserved inside error_dict
.
You can try this:
inst = MyDjangoModel(name="Foo", attribute=0)
try:
inst.full_clean()
except ValidationError as exc:
for original_exc in exc.error_dict['__all__']:
if isinstance(original_exc, MyDjangoModel.CustomValidationError):
print("Hello!")
elif isinstance(original_exc, ValidationError):
print("Bye!")
Assuming that CustomValidationError
is only raised from the clean
method. Otherwise you would also need to check other keys in error_dict
.
Note that the order of the if
s is important: the second one would also be True if the first one is True.