Как проверить, был ли создан подкласс Django ValidationError? - PullRequest
0 голосов
/ 21 ноября 2018

Предположим, у меня есть модель 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 голосов
/ 21 ноября 2018

Метод 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 s важен: второй также будет True, если первый - True.

...