summaryrefslogtreecommitdiff
path: root/django/core/exceptions.py
diff options
context:
space:
mode:
authorLoic Bistuer <loic.bistuer@sixmedia.com>2013-04-05 02:21:57 +0700
committerTim Graham <timograham@gmail.com>2013-06-18 08:01:17 -0400
commitf34cfec0fa1243b4a3b9865b961a2360f211f0d8 (patch)
tree612b00512e706da872dd3883a70809d37b5bd8cd /django/core/exceptions.py
parentefe6e16008b4a123666cc445f7319efce8e9b6bf (diff)
downloaddjango-f34cfec0fa1243b4a3b9865b961a2360f211f0d8.tar.gz
Refactored ValidationError to allow persisting error params and error codes as the exception bubbles up
Diffstat (limited to 'django/core/exceptions.py')
-rw-r--r--django/core/exceptions.py68
1 files changed, 46 insertions, 22 deletions
diff --git a/django/core/exceptions.py b/django/core/exceptions.py
index 2c79736e33..5975164d07 100644
--- a/django/core/exceptions.py
+++ b/django/core/exceptions.py
@@ -3,6 +3,9 @@ Global Django exception and warning classes.
"""
import logging
from functools import reduce
+import operator
+
+from django.utils.encoding import force_text
class DjangoRuntimeWarning(RuntimeWarning):
@@ -74,46 +77,67 @@ NON_FIELD_ERRORS = '__all__'
class ValidationError(Exception):
"""An error while validating data."""
def __init__(self, message, code=None, params=None):
- import operator
- from django.utils.encoding import force_text
"""
ValidationError can be passed any object that can be printed (usually
a string), a list of objects or a dictionary.
"""
if isinstance(message, dict):
- self.message_dict = message
- # Reduce each list of messages into a single list.
- message = reduce(operator.add, message.values())
-
- if isinstance(message, list):
- self.messages = [force_text(msg) for msg in message]
+ self.error_dict = message
+ elif isinstance(message, list):
+ self.error_list = message
else:
self.code = code
self.params = params
- message = force_text(message)
- self.messages = [message]
+ self.message = message
+ self.error_list = [self]
+
+ @property
+ def message_dict(self):
+ message_dict = {}
+ for field, messages in self.error_dict.items():
+ message_dict[field] = []
+ for message in messages:
+ if isinstance(message, ValidationError):
+ message_dict[field].extend(message.messages)
+ else:
+ message_dict[field].append(force_text(message))
+ return message_dict
+
+ @property
+ def messages(self):
+ if hasattr(self, 'error_dict'):
+ message_list = reduce(operator.add, self.error_dict.values())
+ else:
+ message_list = self.error_list
+
+ messages = []
+ for message in message_list:
+ if isinstance(message, ValidationError):
+ params = message.params
+ message = message.message
+ if params:
+ message %= params
+ message = force_text(message)
+ else:
+ message = force_text(message)
+ messages.append(message)
+ return messages
def __str__(self):
- # This is needed because, without a __str__(), printing an exception
- # instance would result in this:
- # AttributeError: ValidationError instance has no attribute 'args'
- # See http://www.python.org/doc/current/tut/node10.html#handling
- if hasattr(self, 'message_dict'):
+ if hasattr(self, 'error_dict'):
return repr(self.message_dict)
return repr(self.messages)
def __repr__(self):
- if hasattr(self, 'message_dict'):
- return 'ValidationError(%s)' % repr(self.message_dict)
- return 'ValidationError(%s)' % repr(self.messages)
+ return 'ValidationError(%s)' % self
def update_error_dict(self, error_dict):
- if hasattr(self, 'message_dict'):
+ if hasattr(self, 'error_dict'):
if error_dict:
- for k, v in self.message_dict.items():
+ for k, v in self.error_dict.items():
error_dict.setdefault(k, []).extend(v)
else:
- error_dict = self.message_dict
+ error_dict = self.error_dict
else:
- error_dict[NON_FIELD_ERRORS] = self.messages
+ error_dict[NON_FIELD_ERRORS] = self.error_list
return error_dict