From 9cc02d4dbe27b6a8b12f958b4fae58573264dde0 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Wed, 19 Dec 2012 12:32:06 +0000 Subject: [PATCH] Dynamic fields are now validated on save (MongoEngine/mongoengine#153) (MongoEngine/mongoengine#154) --- AUTHORS | 3 ++- docs/changelog.rst | 1 + mongoengine/base/document.py | 3 +++ mongoengine/fields.py | 4 ++++ tests/document/dynamic.py | 23 +++++++++++++++++++++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 2519c89d..794f297d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -129,4 +129,5 @@ that much better: * Peter Teichman * Jakub Kot * Jorge Bastida - * Stefan Wójcik \ No newline at end of file + * Stefan Wójcik + * Pete Campton \ No newline at end of file diff --git a/docs/changelog.rst b/docs/changelog.rst index 845f3a9e..fa0fe100 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -20,6 +20,7 @@ Changes in 0.8 - Inheritance is off by default (MongoEngine/mongoengine#122) - Remove _types and just use _cls for inheritance (MongoEngine/mongoengine#148) - Only allow QNode instances to be passed as query objects (MongoEngine/mongoengine#199) +- Dynamic fields are now validated on save (MongoEngine/mongoengine#153) (MongoEngine/mongoengine#154) Changes in 0.7.9 ================ diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 2dd4b03b..a3f10f52 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -245,6 +245,9 @@ class BaseDocument(object): # Get a list of tuples of field names and their current values fields = [(field, self._data.get(name)) for name, field in self._fields.items()] + if self._dynamic: + fields += [(field, self._data.get(name)) + for name, field in self._dynamic_fields.items()] EmbeddedDocumentField = _import_class("EmbeddedDocumentField") GenericEmbeddedDocumentField = _import_class("GenericEmbeddedDocumentField") diff --git a/mongoengine/fields.py b/mongoengine/fields.py index fe94d351..73c0db4d 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -564,6 +564,10 @@ class DynamicField(BaseField): return StringField().prepare_query_value(op, value) return self.to_mongo(value) + def validate(self, value, clean=True): + if hasattr(value, "validate"): + value.validate(clean=clean) + class ListField(ComplexBaseField): """A list field that wraps a standard field, allowing multiple instances diff --git a/tests/document/dynamic.py b/tests/document/dynamic.py index d879b54c..ca0db0a3 100644 --- a/tests/document/dynamic.py +++ b/tests/document/dynamic.py @@ -122,6 +122,29 @@ class DynamicTest(unittest.TestCase): self.assertEqual(1, self.Person.objects(misc__hello='world').count()) + def test_complex_embedded_document_validation(self): + """Ensure embedded dynamic documents may be validated""" + class Embedded(DynamicEmbeddedDocument): + content = URLField() + + class Doc(DynamicDocument): + pass + + Doc.drop_collection() + doc = Doc() + + embedded_doc_1 = Embedded(content='http://mongoengine.org') + embedded_doc_1.validate() + + embedded_doc_2 = Embedded(content='this is not a url') + with self.assertRaises(ValidationError): + embedded_doc_2.validate() + + doc.embedded_field_1 = embedded_doc_1 + doc.embedded_field_2 = embedded_doc_2 + with self.assertRaises(ValidationError): + doc.validate() + def test_inheritance(self): """Ensure that dynamic document plays nice with inheritance""" class Employee(self.Person):