Source code for django_sorcery.exceptions

"""Exceptions."""

from django.core.exceptions import ValidationError


[docs]class NestedValidationError(ValidationError): """Django Validation error except which allows nested errors. Useful for validating composite objects. For example:: raise NestedValidationError({ "field": ["error"], "composite": { "field": ["error"], } }) """ def __init__(self, message, code=None, params=None): if isinstance(message, dict): self.error_dict = {} for field, messages in message.items(): _messages = messages if not isinstance(messages, ValidationError): _messages = NestedValidationError(messages) try: self.error_dict[field] = _messages.error_list except AttributeError: self.error_dict[field] = _messages.error_dict elif isinstance(message, list): self.error_list = [] for m in message: _m = m if not isinstance(m, ValidationError): _m = NestedValidationError(m) try: self.error_list.extend(_m.error_list) except AttributeError: self.error_list.append(_m) elif isinstance(message, NestedValidationError): self.__dict__.update(vars(message)) else: super().__init__(message, code, params)
[docs] def update_error_dict(self, error_dict): if not hasattr(self, "error_dict"): return super().update_error_dict(error_dict) for field, errors in self.error_dict.items(): holder = error_dict.setdefault(field, errors.__class__()) (getattr(holder, "update", None) or holder.extend)(errors) return error_dict
def __iter__(self): if hasattr(self, "code"): yield from super().__iter__() elif hasattr(self, "error_dict"): for field, errors in self.error_dict.items(): errors = NestedValidationError(errors) if hasattr(errors, "error_dict"): yield field, dict(errors) else: yield field, list(errors) else: for errors in self.error_list: errors = NestedValidationError(errors) if hasattr(errors, "error_dict"): yield dict(errors) else: yield from errors def __repr__(self): return "Nested" + super().__repr__()