From fdc385ea3389210f2da1eff5a1eb6a2cdf911dcd Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Wed, 30 Nov 2011 03:06:46 -0800 Subject: [PATCH] Allow dynamic data to be deleted Fixes #374 --- AUTHORS | 1 + docs/changelog.rst | 1 + mongoengine/document.py | 9 +++++++++ tests/dynamic_document.py | 27 +++++++++++++++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/AUTHORS b/AUTHORS index d36d3f2f..7e7c3321 100644 --- a/AUTHORS +++ b/AUTHORS @@ -78,3 +78,4 @@ that much better: * jonrscott * Alice Zoƫ Bevan-McGregor * Stephen Young + * tkloc diff --git a/docs/changelog.rst b/docs/changelog.rst index bd5cf564..055cf92c 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,6 +5,7 @@ Changelog Changes in dev ============== +- Fixed deletion of dynamic data - Added support for the $elementMatch operator - Added reverse option to SortedListFields - Fixed dereferencing - multi directional list dereferencing diff --git a/mongoengine/document.py b/mongoengine/document.py index a9ab1033..e22e36ff 100644 --- a/mongoengine/document.py +++ b/mongoengine/document.py @@ -329,6 +329,15 @@ class DynamicDocument(Document): __metaclass__ = TopLevelDocumentMetaclass _dynamic = True + def __delattr__(self, *args, **kwargs): + """Deletes the attribute by setting to None and allowing _delta to unset + it""" + field_name = args[0] + if field_name in self._dynamic_fields: + setattr(self, field_name, None) + else: + super(DynamicDocument, self).__delattr__(*args, **kwargs) + class DynamicEmbeddedDocument(EmbeddedDocument): """A Dynamic Embedded Document class allowing flexible, expandable and diff --git a/tests/dynamic_document.py b/tests/dynamic_document.py index 19cd4665..3d808a18 100644 --- a/tests/dynamic_document.py +++ b/tests/dynamic_document.py @@ -50,6 +50,33 @@ class DynamicDocTest(unittest.TestCase): p = self.Person.objects.get() self.assertEquals(p.misc, {'hello': 'world'}) + def test_delete_dynamic_field(self): + """Test deleting a dynamic field works""" + self.Person.drop_collection() + p = self.Person() + p.name = "Dean" + p.misc = 22 + p.save() + + p = self.Person.objects.get() + p.misc = {'hello': 'world'} + p.save() + + p = self.Person.objects.get() + self.assertEquals(p.misc, {'hello': 'world'}) + collection = self.db[self.Person._get_collection_name()] + obj = collection.find_one() + self.assertEquals(sorted(obj.keys()), ['_cls', '_id', '_types', 'misc', 'name']) + + del(p.misc) + p.save() + + p = self.Person.objects.get() + self.assertFalse(hasattr(p, 'misc')) + + obj = collection.find_one() + self.assertEquals(sorted(obj.keys()), ['_cls', '_id', '_types', 'name']) + def test_dynamic_document_queries(self): """Ensure we can query dynamic fields""" p = self.Person()