Fixes saving document schemas that have changed
Ensures that form defaults which are documents are automatically marked as changed, so schemas can evolve without migration issues. [#360]
This commit is contained in:
parent
34646a414c
commit
63c5a4dd65
1
AUTHORS
1
AUTHORS
@ -74,4 +74,5 @@ that much better:
|
||||
* Marc Tamlyn
|
||||
* Karim Allah
|
||||
* Adam Parrish
|
||||
* jpfarias
|
||||
|
||||
|
@ -5,6 +5,7 @@ Changelog
|
||||
Changes in dev
|
||||
==============
|
||||
|
||||
- Fixed document mutation saving issue
|
||||
- Fixed positional operator when replacing embedded documents
|
||||
- Added Non-Django Style choices back (you can have either)
|
||||
- Fixed __repr__ of a sliced queryset
|
||||
|
@ -883,14 +883,21 @@ class BaseDocument(object):
|
||||
""".strip() % class_name)
|
||||
cls = subclasses[class_name]
|
||||
|
||||
changed_fields = []
|
||||
for field_name, field in cls._fields.items():
|
||||
if field.db_field in data:
|
||||
value = data[field.db_field]
|
||||
data[field_name] = (value if value is None
|
||||
else field.to_python(value))
|
||||
elif field.default:
|
||||
default = field.default
|
||||
if callable(default):
|
||||
default = default()
|
||||
if isinstance(default, BaseDocument):
|
||||
changed_fields.append(field_name)
|
||||
|
||||
obj = cls(**data)
|
||||
obj._changed_fields = []
|
||||
obj._changed_fields = changed_fields
|
||||
return obj
|
||||
|
||||
def _mark_as_changed(self, key):
|
||||
|
@ -2360,6 +2360,36 @@ class DocumentTest(unittest.TestCase):
|
||||
|
||||
self.assertRaises(InvalidDocumentError, throw_invalid_document_error)
|
||||
|
||||
def test_mutating_documents(self):
|
||||
|
||||
class B(EmbeddedDocument):
|
||||
field1 = StringField(default='field1')
|
||||
|
||||
class A(Document):
|
||||
b = EmbeddedDocumentField(B, default=lambda: B())
|
||||
|
||||
A.drop_collection()
|
||||
a = A()
|
||||
a.save()
|
||||
a.reload()
|
||||
self.assertEquals(a.b.field1, 'field1')
|
||||
|
||||
class C(EmbeddedDocument):
|
||||
c_field = StringField(default='cfield')
|
||||
|
||||
class B(EmbeddedDocument):
|
||||
field1 = StringField(default='field1')
|
||||
field2 = EmbeddedDocumentField(C, default=lambda: C())
|
||||
|
||||
class A(Document):
|
||||
b = EmbeddedDocumentField(B, default=lambda: B())
|
||||
|
||||
a = A.objects()[0]
|
||||
a.b.field2.c_field = 'new value'
|
||||
a.save()
|
||||
|
||||
a.reload()
|
||||
self.assertEquals(a.b.field2.c_field, 'new value')
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user