Added custom cascade kwarg options

Allows the user to overwrite any default kwargs

Closes #295
This commit is contained in:
Ross Lawley 2011-11-30 08:54:33 -08:00
parent 0187a0e113
commit 9188f9bf62
4 changed files with 42 additions and 6 deletions

View File

@ -81,3 +81,4 @@ that much better:
* tkloc * tkloc
* aid * aid
* yamaneko1212 * yamaneko1212
* dave mankoff

View File

@ -5,7 +5,8 @@ Changelog
Changes in dev 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 - Removed Document._get_subclasses() - no longer required
- Fixed bug requiring subclasses when not actually needed - Fixed bug requiring subclasses when not actually needed
- Fixed deletion of dynamic data - Fixed deletion of dynamic data

View File

@ -121,7 +121,7 @@ class Document(BaseDocument):
return self._collection return self._collection
def save(self, safe=True, force_insert=False, validate=True, write_options=None, 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 """Save the :class:`~mongoengine.Document` to the database. If the
document already exists, it will be updated, otherwise it will be document already exists, it will be updated, otherwise it will be
created. created.
@ -141,6 +141,7 @@ class Document(BaseDocument):
have recorded the write and will force an fsync on each server being written to. 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 :param cascade: Sets the flag for cascading saves. You can set a default by setting
"cascade" in the document __meta__ "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 :param _refs: A list of processed references used in cascading saves
.. versionchanged:: 0.5 .. versionchanged:: 0.5
@ -150,6 +151,8 @@ class Document(BaseDocument):
.. versionchanged:: 0.6 .. versionchanged:: 0.6
Cascade saves are optional = defaults to True, if you want fine grain Cascade saves are optional = defaults to True, if you want fine grain
control then you can turn off using document meta['cascade'] = False 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) 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 cascade = self._meta.get('cascade', True) if cascade is None else cascade
if cascade: if cascade:
self.cascade_save(safe=safe, force_insert=force_insert, kwargs = {
validate=validate, write_options=write_options, "safe": safe,
cascade=cascade, _refs=_refs) "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: except pymongo.errors.OperationFailure, err:
message = 'Could not save document (%s)' message = 'Could not save document (%s)'

View File

@ -159,7 +159,7 @@ class DocumentTest(unittest.TestCase):
self.assertEqual(Dog._superclasses, dog_superclasses) 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. """Ensure that the correct list of sub and super classes is assembled.
when importing part of the model when importing part of the model
""" """
@ -1200,6 +1200,29 @@ class DocumentTest(unittest.TestCase):
p1.reload() p1.reload()
self.assertEquals(p1.name, p.parent.name) 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): def test_save_cascade_meta(self):
class Person(Document): class Person(Document):