Home > OS >  How show val er
How show val er

Time:03-18

Need some help with the if statements and Vaidation errors.

Right now I have this function:

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 not Sunny')
    validated_data['calculate'] = Account.NEW
    return validated_data

Need to add another if statement:

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

If I add another if not statement in this function it's not going to the second one if not and raising the first Validation error. I would like that this function checking all if's and raising Validation error for the each case.

CodePudding user response:

From what I understand, you want both the Moon and Sunny errors to be raised. However, this cannot happen: if the first is raised, then the second will never be reached. If the first is not raised, only then can the second be raised. But both can't be raised at the same time.

CodePudding user response:

One solution, do it in a loop:

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

CodePudding user response:

It is unusual to want to do this, and handling your exceptions elsewhere might be tricky, but you could raise an Exception of Exceptions something like this:

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

CodePudding user response:

You can't raise two exceptions at once, but you can define your own Exception subclass that incorporates arbitrary data. For example, you could store a list of multiple error messages:

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)

and then accumulate multiple messages before deciding to raise:

    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
  • Related