Merge pull request #927 from Catstyle/feature/mark_as_changed_issue

mark_as_changed issue
This commit is contained in:
Omer Katz 2015-04-10 12:06:00 +03:00
commit 19dc312128
4 changed files with 65 additions and 1 deletions

View File

@ -220,3 +220,4 @@ that much better:
* J. Fernando Sánchez (https://github.com/balkian) * J. Fernando Sánchez (https://github.com/balkian)
* Michael Chase (https://github.com/rxsegrxup) * Michael Chase (https://github.com/rxsegrxup)
* Eremeev Danil (https://github.com/elephanter) * Eremeev Danil (https://github.com/elephanter)
* Catstyle Lee (https://github.com/Catstyle)

View File

@ -5,6 +5,7 @@ Changelog
Changes in 0.9.X - DEV Changes in 0.9.X - DEV
====================== ======================
- Fixed mark_as_changed to handle higher/lower level fields changed. #927
- ListField of embedded docs doesn't set the _instance attribute when iterating over it #914 - ListField of embedded docs doesn't set the _instance attribute when iterating over it #914
- Support += and *= for ListField #595 - Support += and *= for ListField #595
- Use sets for populating dbrefs to dereference - Use sets for populating dbrefs to dereference

View File

@ -483,7 +483,19 @@ class BaseDocument(object):
key = self._db_field_map.get(key, key) key = self._db_field_map.get(key, key)
if key not in self._changed_fields: if key not in self._changed_fields:
self._changed_fields.append(key) levels, idx = key.split('.'), 1
while idx <= len(levels):
if '.'.join(levels[:idx]) in self._changed_fields:
break
idx += 1
else:
self._changed_fields.append(key)
# remove lower level changed fields
level = '.'.join(levels[:idx]) + '.'
remove = self._changed_fields.remove
for field in self._changed_fields:
if field.startswith(level):
remove(field)
def _clear_changed_fields(self): def _clear_changed_fields(self):
"""Using get_changed_fields iterate and remove any fields that are """Using get_changed_fields iterate and remove any fields that are

View File

@ -735,6 +735,56 @@ class DeltaTest(unittest.TestCase):
mydoc._clear_changed_fields() mydoc._clear_changed_fields()
self.assertEqual([], mydoc._get_changed_fields()) self.assertEqual([], mydoc._get_changed_fields())
def test_lower_level_mark_as_changed(self):
class EmbeddedDoc(EmbeddedDocument):
name = StringField()
class MyDoc(Document):
subs = MapField(EmbeddedDocumentField(EmbeddedDoc))
MyDoc.drop_collection()
MyDoc().save()
mydoc = MyDoc.objects.first()
mydoc.subs['a'] = EmbeddedDoc()
self.assertEqual(["subs.a"], mydoc._get_changed_fields())
subdoc = mydoc.subs['a']
subdoc.name = 'bar'
self.assertEqual(["name"], subdoc._get_changed_fields())
self.assertEqual(["subs.a"], mydoc._get_changed_fields())
mydoc.save()
mydoc._clear_changed_fields()
self.assertEqual([], mydoc._get_changed_fields())
def test_upper_level_mark_as_changed(self):
class EmbeddedDoc(EmbeddedDocument):
name = StringField()
class MyDoc(Document):
subs = MapField(EmbeddedDocumentField(EmbeddedDoc))
MyDoc.drop_collection()
MyDoc(subs={'a': EmbeddedDoc(name='foo')}).save()
mydoc = MyDoc.objects.first()
subdoc = mydoc.subs['a']
subdoc.name = 'bar'
self.assertEqual(["name"], subdoc._get_changed_fields())
self.assertEqual(["subs.a.name"], mydoc._get_changed_fields())
mydoc.subs['a'] = EmbeddedDoc()
self.assertEqual(["subs.a"], mydoc._get_changed_fields())
mydoc.save()
mydoc._clear_changed_fields()
self.assertEqual([], mydoc._get_changed_fields())
def test_referenced_object_changed_attributes(self): def test_referenced_object_changed_attributes(self):
"""Ensures that when you save a new reference to a field, the referenced object isn't altered""" """Ensures that when you save a new reference to a field, the referenced object isn't altered"""