首页 > 解决方案 > How to check if Django ValidationError subclass was raised?

问题描述

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?

标签: pythondjangopython-2.7django-1.6

解决方案


full_clean方法收集了几个阶段引发的所有错误。

你可以在这里查看它是如何调用你的clean方法的:https ://github.com/django/django/blob/master/django/db/models/base.py#L1150

幸运的是,原始异常保存在error_dict.

你可以试试这个:

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!")

假设这CustomValidationError只是从clean方法中提出的。否则,您还需要检查error_dict.

请注意,ifs 的顺序很重要:如果第一个为 True,则第二个也为 True。


推荐阅读