From 9188f9bf62c63d23537e69911d5aef1411e66008 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Wed, 30 Nov 2011 08:54:33 -0800 Subject: [PATCH] Added custom cascade kwarg options Allows the user to overwrite any default kwargs Closes #295 --- AUTHORS | 1 + docs/changelog.rst | 3 ++- mongoengine/document.py | 19 +++++++++++++++---- tests/document.py | 25 ++++++++++++++++++++++++- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/AUTHORS b/AUTHORS index bcf6129e..0dce8c41 100644 --- a/AUTHORS +++ b/AUTHORS @@ -81,3 +81,4 @@ that much better: * tkloc * aid * yamaneko1212 + * dave mankoff diff --git a/docs/changelog.rst b/docs/changelog.rst index 602294a1..b0fe6806 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,7 +5,8 @@ Changelog Changes in dev ============== -- Fixed Handle None values for non-required fields. +- Added customisable cascade kwarg options +- Fixed Handle None values for non-required fields - Removed Document._get_subclasses() - no longer required - Fixed bug requiring subclasses when not actually needed - Fixed deletion of dynamic data diff --git a/mongoengine/document.py b/mongoengine/document.py index 0eee4af6..3f4c9d77 100644 --- a/mongoengine/document.py +++ b/mongoengine/document.py @@ -121,7 +121,7 @@ class Document(BaseDocument): return self._collection def save(self, safe=True, force_insert=False, validate=True, write_options=None, - cascade=None, _refs=None): + cascade=None, cascade_kwargs=None, _refs=None): """Save the :class:`~mongoengine.Document` to the database. If the document already exists, it will be updated, otherwise it will be created. @@ -141,6 +141,7 @@ class Document(BaseDocument): have recorded the write and will force an fsync on each server being written to. :param cascade: Sets the flag for cascading saves. You can set a default by setting "cascade" in the document __meta__ + :param cascade_kwargs: optional kwargs dictionary to be passed throw to cascading saves :param _refs: A list of processed references used in cascading saves .. versionchanged:: 0.5 @@ -150,6 +151,8 @@ class Document(BaseDocument): .. versionchanged:: 0.6 Cascade saves are optional = defaults to True, if you want fine grain control then you can turn off using document meta['cascade'] = False + Also you can pass different kwargs to the cascade save using cascade_kwargs + which overwrites the existing kwargs with custom values """ signals.pre_save.send(self.__class__, document=self) @@ -180,9 +183,17 @@ class Document(BaseDocument): cascade = self._meta.get('cascade', True) if cascade is None else cascade if cascade: - self.cascade_save(safe=safe, force_insert=force_insert, - validate=validate, write_options=write_options, - cascade=cascade, _refs=_refs) + kwargs = { + "safe": safe, + "force_insert": force_insert, + "validate": validate, + "write_options": write_options, + "cascade": cascade + } + if cascade_kwargs: # Allow granular control over cascades + kwargs.update(cascade_kwargs) + kwargs['_refs'] = _refs + self.cascade_save(**kwargs) except pymongo.errors.OperationFailure, err: message = 'Could not save document (%s)' diff --git a/tests/document.py b/tests/document.py index ca42c091..f12affd4 100644 --- a/tests/document.py +++ b/tests/document.py @@ -159,7 +159,7 @@ class DocumentTest(unittest.TestCase): self.assertEqual(Dog._superclasses, dog_superclasses) - def test_external_super_and_sub_classes(self): + def test_external_superclasses(self): """Ensure that the correct list of sub and super classes is assembled. when importing part of the model """ @@ -1200,6 +1200,29 @@ class DocumentTest(unittest.TestCase): p1.reload() self.assertEquals(p1.name, p.parent.name) + def test_save_cascade_kwargs(self): + + class Person(Document): + name = StringField() + parent = ReferenceField('self') + + Person.drop_collection() + + p1 = Person(name="Wilson Snr") + p1.parent = None + p1.save() + + p2 = Person(name="Wilson Jr") + p2.parent = p1 + p2.save(force_insert=True, cascade_kwargs={"force_insert": False}) + + p = Person.objects(name="Wilson Jr").get() + p.parent.name = "Daddy Wilson" + p.save() + + p1.reload() + self.assertEquals(p1.name, p.parent.name) + def test_save_cascade_meta(self): class Person(Document):