From 1b17fb0ae7d09503dff574a12face242354e6fd3 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Thu, 19 Jul 2012 15:04:12 +0100 Subject: [PATCH] Updated validation error messages refs hmarr/mongoengine#539 --- docs/changelog.rst | 1 + mongoengine/base.py | 27 +++++++++++++++------------ tests/test_document.py | 10 ++++------ tests/test_fields.py | 2 +- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 466fdcbf..b4d747d0 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,7 @@ Changelog Changes in 0.6.15 ================= +- Updated validation error message - Added support for null / zero / false values in item_frequencies - Fixed cascade save edge case - Fixed geo index creation through reference fields diff --git a/mongoengine/base.py b/mongoengine/base.py index 0d216d97..3ab6850f 100644 --- a/mongoengine/base.py +++ b/mongoengine/base.py @@ -1,4 +1,5 @@ import warnings +from collections import defaultdict from queryset import QuerySet, QuerySetManager from queryset import DoesNotExist, MultipleObjectsReturned @@ -53,9 +54,9 @@ class ValidationError(AssertionError): message = super(ValidationError, self).__getattribute__(name) if name == 'message': if self.field_name: - message = '%s ("%s")' % (message, self.field_name) + message = '%s' % message if self.errors: - message = '%s:\n%s' % (message, self._format_errors()) + message = '%s(%s)' % (message, self._format_errors()) return message def _get_message(self): @@ -93,17 +94,20 @@ class ValidationError(AssertionError): def _format_errors(self): """Returns a string listing all errors within a document""" - def format_error(field, value, prefix=''): - prefix = "%s.%s" % (prefix, field) if prefix else "%s" % field + def generate_key(value, prefix=''): + if isinstance(value, list): + value = ' '.join([generate_key(k) for k in value]) if isinstance(value, dict): + value = ' '.join( + [generate_key(v, k) for k, v in value.iteritems()]) - return '\n'.join( - [format_error(k, value[k], prefix) for k in value]) - else: - return "%s: %s" % (prefix, value) + results = "%s.%s" % (prefix, value) if prefix else value + return results - return '\n'.join( - [format_error(k, v) for k, v in self.to_dict().items()]) + error_dict = defaultdict(list) + for k, v in self.to_dict().iteritems(): + error_dict[generate_key(v)].append(k) + return ' '.join(["%s: %s" % (k, v) for k, v in error_dict.iteritems()]) _document_registry = {} @@ -899,8 +903,7 @@ class BaseDocument(object): errors[field.name] = ValidationError('Field is required', field_name=field.name) if errors: - raise ValidationError('Errors encountered validating document', - errors=errors) + raise ValidationError('ValidationError', errors=errors) def to_mongo(self): """Return data dictionary ready for use with MongoDB. diff --git a/tests/test_document.py b/tests/test_document.py index 992c2832..82508618 100644 --- a/tests/test_document.py +++ b/tests/test_document.py @@ -3137,7 +3137,7 @@ class ValidatorErrorTest(unittest.TestCase): self.assertEquals(error.to_dict()['1st']['2nd']['3rd']['4th'], 'Inception') - self.assertEquals(error.message, "root:\n1st.2nd.3rd.4th: Inception") + self.assertEquals(error.message, "root(2nd.3rd.4th.Inception: ['1st'])") def test_model_validation(self): @@ -3148,13 +3148,11 @@ class ValidatorErrorTest(unittest.TestCase): try: User().validate() except ValidationError, e: - expected_error_message = """Errors encountered validating document: -username: Field is required ("username") -name: Field is required ("name")""" + expected_error_message = """ValidationError(Field is required: ['username', 'name'])""" self.assertEquals(e.message, expected_error_message) self.assertEquals(e.to_dict(), { - 'username': 'Field is required ("username")', - 'name': u'Field is required ("name")'}) + 'username': 'Field is required', + 'name': 'Field is required'}) def test_spaces_in_keys(self): diff --git a/tests/test_fields.py b/tests/test_fields.py index 2c7e6946..88dfbf58 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -2122,7 +2122,7 @@ class FieldTest(unittest.TestCase): self.assertTrue(1 in error_dict['comments']) self.assertTrue('content' in error_dict['comments'][1]) self.assertEquals(error_dict['comments'][1]['content'], - u'Field is required ("content")') + 'Field is required') post.comments[1].content = 'here we go' post.validate()