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
|
* Marc Tamlyn
|
||||||
* Karim Allah
|
* Karim Allah
|
||||||
* Adam Parrish
|
* Adam Parrish
|
||||||
|
* jpfarias
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ Changelog
|
|||||||
Changes in dev
|
Changes in dev
|
||||||
==============
|
==============
|
||||||
|
|
||||||
|
- Fixed document mutation saving issue
|
||||||
- Fixed positional operator when replacing embedded documents
|
- Fixed positional operator when replacing embedded documents
|
||||||
- Added Non-Django Style choices back (you can have either)
|
- Added Non-Django Style choices back (you can have either)
|
||||||
- Fixed __repr__ of a sliced queryset
|
- Fixed __repr__ of a sliced queryset
|
||||||
|
@ -883,14 +883,21 @@ class BaseDocument(object):
|
|||||||
""".strip() % class_name)
|
""".strip() % class_name)
|
||||||
cls = subclasses[class_name]
|
cls = subclasses[class_name]
|
||||||
|
|
||||||
|
changed_fields = []
|
||||||
for field_name, field in cls._fields.items():
|
for field_name, field in cls._fields.items():
|
||||||
if field.db_field in data:
|
if field.db_field in data:
|
||||||
value = data[field.db_field]
|
value = data[field.db_field]
|
||||||
data[field_name] = (value if value is None
|
data[field_name] = (value if value is None
|
||||||
else field.to_python(value))
|
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 = cls(**data)
|
||||||
obj._changed_fields = []
|
obj._changed_fields = changed_fields
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def _mark_as_changed(self, key):
|
def _mark_as_changed(self, key):
|
||||||
|
@ -2360,6 +2360,36 @@ class DocumentTest(unittest.TestCase):
|
|||||||
|
|
||||||
self.assertRaises(InvalidDocumentError, throw_invalid_document_error)
|
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__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user