From 77ebd87fed43e6a41565b12dc78d4861360b6fc5 Mon Sep 17 00:00:00 2001 From: Meir Kriheli Date: Thu, 7 Jun 2012 12:02:19 +0300 Subject: [PATCH 1/4] Test PULL reverse_delete_rule --- tests/queryset.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/queryset.py b/tests/queryset.py index 3b662489..191afcfe 100644 --- a/tests/queryset.py +++ b/tests/queryset.py @@ -1388,6 +1388,36 @@ class QuerySetTest(unittest.TestCase): self.assertRaises(OperationError, self.Person.objects.delete) + def test_reverse_delete_rule_pull(self): + """Ensure pulling of references to deleted documents. + """ + class BlogPost(Document): + content = StringField() + authors = ListField(ReferenceField(self.Person, + reverse_delete_rule=PULL)) + + BlogPost.drop_collection() + self.Person.drop_collection() + + me = self.Person(name='Test User') + me.save() + + someoneelse = self.Person(name='Some-one Else') + someoneelse.save() + + post = BlogPost(content='Watching TV', authors=[me, someoneelse]) + post.save() + + another = BlogPost(content='Chilling Out', authors=[someoneelse]) + another.save() + + someoneelse.delete() + post.reload() + another.reload() + + self.assertEqual(post.authors, [me]) + self.assertEqual(another.authors, []) + def test_update(self): """Ensure that atomic updates work properly. """ From 8060179f6de35791e6218e861b03202b1e60f498 Mon Sep 17 00:00:00 2001 From: Meir Kriheli Date: Thu, 7 Jun 2012 12:16:00 +0300 Subject: [PATCH 2/4] Implement PULL reverse_delete_rule --- mongoengine/queryset.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index 1fb3eda7..c943dc4d 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -10,7 +10,7 @@ from bson.code import Code from mongoengine import signals __all__ = ['queryset_manager', 'Q', 'InvalidQueryError', - 'DO_NOTHING', 'NULLIFY', 'CASCADE', 'DENY'] + 'DO_NOTHING', 'NULLIFY', 'CASCADE', 'DENY', 'PULL'] # The maximum number of items to display in a QuerySet.__repr__ @@ -21,6 +21,7 @@ DO_NOTHING = 0 NULLIFY = 1 CASCADE = 2 DENY = 3 +PULL = 4 class DoesNotExist(Exception): @@ -1319,6 +1320,10 @@ class QuerySet(object): document_cls.objects(**{field_name + '__in': self}).update( safe_update=safe, **{'unset__%s' % field_name: 1}) + elif rule == PULL: + document_cls.objects(**{field_name + '__in': self}).update( + safe_update=safe, + **{'pull_all__%s' % field_name: self}) self._collection.remove(self._query, safe=safe) From 26db9d8a9d18869ef4bee19454e706b94bfcb9ad Mon Sep 17 00:00:00 2001 From: Meir Kriheli Date: Thu, 7 Jun 2012 12:32:02 +0300 Subject: [PATCH 3/4] Documentation for PULL reverse_delete_rule --- docs/changelog.rst | 4 ++++ docs/guide/defining-documents.rst | 4 ++++ mongoengine/fields.py | 2 ++ 3 files changed, 10 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 02887fd6..67b798ac 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -2,6 +2,10 @@ Changelog ========= +Changes in 0.6.x +================= +- PULL reverse_delete_rule + Changes in 0.6.10 ================= - Fixed basedict / baselist to return super(..) diff --git a/docs/guide/defining-documents.rst b/docs/guide/defining-documents.rst index ba7a5801..a005ddd3 100644 --- a/docs/guide/defining-documents.rst +++ b/docs/guide/defining-documents.rst @@ -289,6 +289,10 @@ Its value can take any of the following constants: :const:`mongoengine.CASCADE` Any object containing fields that are refererring to the object being deleted are deleted first. +:const:`mongoengine.PULL` + Removes the reference to the object (using MongoDB's "pull" operation) + from any object's fields of + :class:`~mongoengine.ListField` (:class:`~mongoengine.ReferenceField`). .. warning:: diff --git a/mongoengine/fields.py b/mongoengine/fields.py index c72c6cb4..df10d33e 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -656,6 +656,8 @@ class ReferenceField(BaseField): * NULLIFY - Updates the reference to null. * CASCADE - Deletes the documents associated with the reference. * DENY - Prevent the deletion of the reference object. + * PULL - Pull the reference from a :class:`~mongoengine.ListField` + of references Alternative syntax for registering delete rules (useful when implementing bi-directional delete rules) From a856c7cc3700086481d5bc357589e5bbe567d1dd Mon Sep 17 00:00:00 2001 From: Meir Kriheli Date: Thu, 7 Jun 2012 12:36:14 +0300 Subject: [PATCH 4/4] Fix formatting of the docstring --- mongoengine/fields.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index df10d33e..ab505f73 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -656,8 +656,7 @@ class ReferenceField(BaseField): * NULLIFY - Updates the reference to null. * CASCADE - Deletes the documents associated with the reference. * DENY - Prevent the deletion of the reference object. - * PULL - Pull the reference from a :class:`~mongoengine.ListField` - of references + * PULL - Pull the reference from a :class:`~mongoengine.ListField` of references Alternative syntax for registering delete rules (useful when implementing bi-directional delete rules)