diff --git a/mongoengine/document.py b/mongoengine/document.py index 06867168..3b812abb 100644 --- a/mongoengine/document.py +++ b/mongoengine/document.py @@ -105,6 +105,19 @@ class Document(BaseDocument): if rule == CASCADE: document_cls.objects(**{field_name: self.id}).delete(safe=safe) + elif rule == NULLIFY: + # TODO: For now, this makes the nullify test pass, but it would + # be nicer to use any of these two atomic versions: + # + # document_cls.objects(**{field_name: self.id}).update(**{'unset__%s' % field_name: 1}) + # or + # document_cls.objects(**{field_name: self.id}).update(**{'set__%s' % field_name: None}) + # + # However, I'm getting ValidationError: 1/None is not a valid ObjectId + # Anybody got a clue? + for doc in document_cls.objects(**{field_name: self.id}): + doc.reviewer = None + doc.save() id_field = self._meta['id_field'] object_id = self._fields[id_field].to_mongo(self[id_field]) diff --git a/tests/document.py b/tests/document.py index d5807c90..7f92320d 100644 --- a/tests/document.py +++ b/tests/document.py @@ -625,7 +625,7 @@ class DocumentTest(unittest.TestCase): BlogPost.drop_collection() - def test_cascade_delete(self): + def test_delete_rule_cascade_and_nullify(self): """Ensure that a referenced document is also deleted upon deletion. """ @@ -633,6 +633,7 @@ class DocumentTest(unittest.TestCase): meta = {'collection': 'blogpost_1'} content = StringField() author = ReferenceField(self.Person, delete_rule=CASCADE) + reviewer = ReferenceField(self.Person, delete_rule=NULLIFY) self.Person.drop_collection() BlogPost.drop_collection() @@ -640,10 +641,18 @@ class DocumentTest(unittest.TestCase): author = self.Person(name='Test User') author.save() + reviewer = self.Person(name='Re Viewer') + reviewer.save() + post = BlogPost(content = 'Watched some TV') post.author = author + post.reviewer = reviewer post.save() + reviewer.delete() + self.assertEqual(len(BlogPost.objects), 1) # No effect on the BlogPost + self.assertEqual(BlogPost.objects.get().reviewer, None) + # Delete the Person, which should lead to deletion of the BlogPost, too author.delete() self.assertEqual(len(BlogPost.objects), 0)