Операторы if в python и ошибка валидации

Нужна помощь с операторами if и ошибками Vaidation.

Сейчас у меня есть такая функция:

def validate(self, validated_data):
    if self.partial:
        validated_data = self.fill_data(self.instance, validated_data)
    if not validated_data['brand'].sunny_account.first():
        raise ValidationError('This brand does not have Sunny enabled')
    validated_data['calculate'] = Account.NEW
    return validated_data

Необходимо добавить еще один оператор if:

if not validated_data['brand'].moon_account.first():
        raise ValidationError('This brand does not have Moon enabled')

Если я добавляю еще один оператор if not в эту функцию, то она не переходит ко второму if not и выдает первую ошибку Validation error. Я бы хотел, чтобы эта функция проверяла все if'ы и выдавала ошибку Validation error для каждого случая.

Одно из решений - сделать это в цикле:

def validate(self, validated_data):
    if self.partial:
        validated_data = self.fill_data(self.instance, validated_data)

    validations = [
        (
            validated_data['brand'].sunny_account.first(), 
            'This brand does not have Sunny enabled'
        ),
        (
            validated_data['brand'].moon_account.first(), 
            'This brand does not have Moon enabled'
        ),
    ]
    
    # Validate
    err_msg = ""
    for cond, msg in validations:
        if not cond:
            # Has error, add the error message
            err_msg = err_msg + msg

    if err_msg:
        # Error message is not empty --> there is an error
        raise ValidationError(err_msg)
    validated_data['calculate'] = Account.NEW
    return validated_data

Насколько я понимаю, вы хотите, чтобы были подняты обе ошибки Moon и Sunny. Однако этого не может произойти: если первая будет поднята, то вторая никогда не будет достигнута. Если первая не будет поднята, то только тогда можно поднять вторую. Но обе ошибки не могут быть подняты одновременно.

Необычно, что вы хотите сделать это, и обработка исключений в другом месте может быть сложной, но вы можете поднять исключение исключений примерно так:

def my_test(thing):
   errors = []
   if thing != 1:
      errors.append(ValidationError('thing 1'))
   if thing != 2:
      errors.append(ValidationError('thing 2'))
   if errors:
      Raise(ValidationError(errors))

Вы не можете raise два исключения одновременно, но вы можете определить свой собственный Exception подкласс, включающий произвольные данные. Например, вы можете хранить список из нескольких сообщений об ошибках:

class ValidationError(Exception):
    def __init__(self):
        super().__init__()
        self._why: list[str] = []

    def __bool__(self) -> bool:
        return bool(self._why)

    def __str__(self) -> str:
        return "\n".join(self._why)

    def add(self, why: str) -> None:
        self._why.append(why)

и затем накапливать множество сообщений, прежде чем принять решение о повышении:

    err = ValidationError()
    if not validated_data['brand'].sunny_account.first():
        err.add('This brand does not have Sunny enabled')
    if not validated_data['brand'].moon_account.first():
        err.add('This brand does not have Moon enabled')
    if err:
        raise err
Вернуться на верх