如何检查是否引发了Django ValidationError子类?

时间:2018-11-21 17:14:37

标签: python django python-2.7 django-1.6

假设我有一个Django模型:

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

我想创建模型实例并对其进行验证:

inst = MyDjangoModel(name="Foo", attribute=0)
try:
    inst.full_clean()
except CustomValidationError:
    print("Hello!")
except ValidationError:
    print("Bye!")

但是上面的代码将永远不会打印"Hello!",因为full_clean方法仅引发ValidationError

有人可以建议如何调用full_clean并检查是否引发了ValidationError子类异常吗?

1 个答案:

答案 0 :(得分:1)

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中的其他键。

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