diff --git a/docs/changelog.rst b/docs/changelog.rst index 19bc4464..601c2dbc 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -42,6 +42,7 @@ Changes in 0.8.X - Added no_dereference method for querysets (#82) (#61) - Undefined data should not override instance methods (#49) - Added Django Group and Permission (#142) +- Added Doc class and pk to Validation messages (#69) Changes in 0.7.9 ================ diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index a88a38bf..4f5a87e5 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -274,7 +274,13 @@ class BaseDocument(object): field_name=field.name) if errors: - raise ValidationError('ValidationError', errors=errors) + pk = "None" + if hasattr(self, 'pk'): + pk = self.pk + elif self._instance: + pk = self._instance.pk + message = "ValidationError (%s:%s) " % (self._class_name, pk) + raise ValidationError(message, errors=errors) def to_json(self): """Converts a document to JSON""" diff --git a/tests/document/instance.py b/tests/document/instance.py index 99e4edb0..3d4e8a97 100644 --- a/tests/document/instance.py +++ b/tests/document/instance.py @@ -466,45 +466,6 @@ class InstanceTest(unittest.TestCase): doc = Doc.objects.get() self.assertEqual(doc, doc.embedded_field[0]._instance) - def test_embedded_document_validation(self): - """Ensure that embedded documents may be validated. - """ - class Comment(EmbeddedDocument): - date = DateTimeField() - content = StringField(required=True) - - comment = Comment() - self.assertRaises(ValidationError, comment.validate) - - comment.content = 'test' - comment.validate() - - comment.date = 4 - self.assertRaises(ValidationError, comment.validate) - - comment.date = datetime.now() - comment.validate() - self.assertEqual(comment._instance, None) - - def test_embedded_db_field_validate(self): - - class SubDoc(EmbeddedDocument): - val = IntField() - - class Doc(Document): - e = EmbeddedDocumentField(SubDoc, db_field='eb') - - Doc.drop_collection() - - Doc(e=SubDoc(val=15)).save() - - doc = Doc.objects.first() - doc.validate() - keys = doc._data.keys() - self.assertEqual(2, len(keys)) - self.assertTrue('id' in keys) - self.assertTrue('e' in keys) - def test_document_clean(self): class TestDocument(Document): status = StringField() @@ -2001,5 +1962,103 @@ class InstanceTest(unittest.TestCase): self.assertEqual("Bar", user._data["foo"]) self.assertEqual([1, 2, 3], user._data["data"]) + + def test_spaces_in_keys(self): + + class Embedded(DynamicEmbeddedDocument): + pass + + class Doc(DynamicDocument): + pass + + Doc.drop_collection() + doc = Doc() + setattr(doc, 'hello world', 1) + doc.save() + + one = Doc.objects.filter(**{'hello world': 1}).count() + self.assertEqual(1, one) + + def test_shard_key(self): + class LogEntry(Document): + machine = StringField() + log = StringField() + + meta = { + 'shard_key': ('machine',) + } + + LogEntry.drop_collection() + + log = LogEntry() + log.machine = "Localhost" + log.save() + + log.log = "Saving" + log.save() + + def change_shard_key(): + log.machine = "127.0.0.1" + + self.assertRaises(OperationError, change_shard_key) + + def test_shard_key_primary(self): + class LogEntry(Document): + machine = StringField(primary_key=True) + log = StringField() + + meta = { + 'shard_key': ('machine',) + } + + LogEntry.drop_collection() + + log = LogEntry() + log.machine = "Localhost" + log.save() + + log.log = "Saving" + log.save() + + def change_shard_key(): + log.machine = "127.0.0.1" + + self.assertRaises(OperationError, change_shard_key) + + def test_kwargs_simple(self): + + class Embedded(EmbeddedDocument): + name = StringField() + + class Doc(Document): + doc_name = StringField() + doc = EmbeddedDocumentField(Embedded) + + classic_doc = Doc(doc_name="my doc", doc=Embedded(name="embedded doc")) + dict_doc = Doc(**{"doc_name": "my doc", + "doc": {"name": "embedded doc"}}) + + self.assertEqual(classic_doc, dict_doc) + self.assertEqual(classic_doc._data, dict_doc._data) + + def test_kwargs_complex(self): + + class Embedded(EmbeddedDocument): + name = StringField() + + class Doc(Document): + doc_name = StringField() + docs = ListField(EmbeddedDocumentField(Embedded)) + + classic_doc = Doc(doc_name="my doc", docs=[ + Embedded(name="embedded doc1"), + Embedded(name="embedded doc2")]) + dict_doc = Doc(**{"doc_name": "my doc", + "docs": [{"name": "embedded doc1"}, + {"name": "embedded doc2"}]}) + + self.assertEqual(classic_doc, dict_doc) + self.assertEqual(classic_doc._data, dict_doc._data) + if __name__ == '__main__': unittest.main() diff --git a/tests/document/validation.py b/tests/document/validation.py index dafb3a39..aaf6b0cc 100644 --- a/tests/document/validation.py +++ b/tests/document/validation.py @@ -3,6 +3,7 @@ import sys sys.path[0:0] = [""] import unittest +from datetime import datetime from mongoengine import * @@ -11,6 +12,9 @@ __all__ = ("ValidatorErrorTest",) class ValidatorErrorTest(unittest.TestCase): + def setUp(self): + connect(db='mongoenginetest') + def test_to_dict(self): """Ensure a ValidationError handles error to_dict correctly. """ @@ -57,25 +61,19 @@ class ValidatorErrorTest(unittest.TestCase): try: User().validate() except ValidationError, e: + self.assertTrue("User:None" in e.message) self.assertEqual(e.to_dict(), { 'username': 'Field is required', 'name': 'Field is required'}) - def test_spaces_in_keys(self): - - class Embedded(DynamicEmbeddedDocument): - pass - - class Doc(DynamicDocument): - pass - - Doc.drop_collection() - doc = Doc() - setattr(doc, 'hello world', 1) - doc.save() - - one = Doc.objects.filter(**{'hello world': 1}).count() - self.assertEqual(1, one) + user = User(username="RossC0", name="Ross").save() + user.name = None + try: + user.save() + except ValidationError, e: + self.assertTrue("User:RossC0" in e.message) + self.assertEqual(e.to_dict(), { + 'name': 'Field is required'}) def test_fields_rewrite(self): class BasePerson(Document): @@ -89,107 +87,60 @@ class ValidatorErrorTest(unittest.TestCase): p = Person(age=15) self.assertRaises(ValidationError, p.validate) - def test_cascaded_save_wrong_reference(self): + def test_embedded_document_validation(self): + """Ensure that embedded documents may be validated. + """ + class Comment(EmbeddedDocument): + date = DateTimeField() + content = StringField(required=True) - class ADocument(Document): - val = IntField() + comment = Comment() + self.assertRaises(ValidationError, comment.validate) - class BDocument(Document): - a = ReferenceField(ADocument) + comment.content = 'test' + comment.validate() - ADocument.drop_collection() - BDocument.drop_collection() + comment.date = 4 + self.assertRaises(ValidationError, comment.validate) - a = ADocument() - a.val = 15 - a.save() + comment.date = datetime.now() + comment.validate() + self.assertEqual(comment._instance, None) - b = BDocument() - b.a = a - b.save() + def test_embedded_db_field_validate(self): - a.delete() - - b = BDocument.objects.first() - b.save(cascade=True) - - def test_shard_key(self): - class LogEntry(Document): - machine = StringField() - log = StringField() - - meta = { - 'shard_key': ('machine',) - } - - LogEntry.drop_collection() - - log = LogEntry() - log.machine = "Localhost" - log.save() - - log.log = "Saving" - log.save() - - def change_shard_key(): - log.machine = "127.0.0.1" - - self.assertRaises(OperationError, change_shard_key) - - def test_shard_key_primary(self): - class LogEntry(Document): - machine = StringField(primary_key=True) - log = StringField() - - meta = { - 'shard_key': ('machine',) - } - - LogEntry.drop_collection() - - log = LogEntry() - log.machine = "Localhost" - log.save() - - log.log = "Saving" - log.save() - - def change_shard_key(): - log.machine = "127.0.0.1" - - self.assertRaises(OperationError, change_shard_key) - - def test_kwargs_simple(self): - - class Embedded(EmbeddedDocument): - name = StringField() + class SubDoc(EmbeddedDocument): + val = IntField(required=True) class Doc(Document): - doc_name = StringField() - doc = EmbeddedDocumentField(Embedded) + id = StringField(primary_key=True) + e = EmbeddedDocumentField(SubDoc, db_field='eb') - classic_doc = Doc(doc_name="my doc", doc=Embedded(name="embedded doc")) - dict_doc = Doc(**{"doc_name": "my doc", - "doc": {"name": "embedded doc"}}) + try: + Doc(id="bad").validate() + except ValidationError, e: + self.assertTrue("SubDoc:None" in e.message) + self.assertEqual(e.to_dict(), { + 'e.val': 'Field is required'}) - self.assertEqual(classic_doc, dict_doc) - self.assertEqual(classic_doc._data, dict_doc._data) + Doc.drop_collection() - def test_kwargs_complex(self): + Doc(id="test", e=SubDoc(val=15)).save() - class Embedded(EmbeddedDocument): - name = StringField() + doc = Doc.objects.first() + keys = doc._data.keys() + self.assertEqual(2, len(keys)) + self.assertTrue('id' in keys) + self.assertTrue('e' in keys) - class Doc(Document): - doc_name = StringField() - docs = ListField(EmbeddedDocumentField(Embedded)) + doc.e.val = "OK" + try: + doc.save() + except ValidationError, e: + self.assertTrue("SubDoc:test" in e.message) + self.assertEqual(e.to_dict(), { + 'e.val': 'Field is required'}) - classic_doc = Doc(doc_name="my doc", docs=[ - Embedded(name="embedded doc1"), - Embedded(name="embedded doc2")]) - dict_doc = Doc(**{"doc_name": "my doc", - "docs": [{"name": "embedded doc1"}, - {"name": "embedded doc2"}]}) - self.assertEqual(classic_doc, dict_doc) - self.assertEqual(classic_doc._data, dict_doc._data) +if __name__ == '__main__': + unittest.main()