diff --git a/AUTHORS b/AUTHORS index dd04aee1..66e181c9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -231,4 +231,5 @@ that much better: * Lars Butler (https://github.com/larsbutler) * George Macon (https://github.com/gmacon) * Ashley Whetter (https://github.com/AWhetter) + * Paul-Armand Verhaegen (https://github.com/paularmand) * Steven Rossiter (https://github.com/BeardedSteve) diff --git a/docs/changelog.rst b/docs/changelog.rst index 7776a99b..c354be18 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -2,8 +2,12 @@ Changelog ========= -Changes in 0.10.4 - DEV -======================= +Changes in 0.10.5 +================= +- Fix for reloading of strict with special fields. #1156 + +Changes in 0.10.4 +================= - SaveConditionError is now importable from the top level package. #1165 - upsert_one method added. #1157 @@ -18,7 +22,7 @@ Changes in 0.10.2 - ReferenceFields now support abstract document types. #837 Changes in 0.10.1 -======================= +================= - Fix infinite recursion with CASCADE delete rules under specific conditions. #1046 - Fix CachedReferenceField bug when loading cached docs as DBRef but failing to save them. #1047 - Fix ignored chained options #842 diff --git a/mongoengine/__init__.py b/mongoengine/__init__.py index 14a7c1ce..791e741e 100644 --- a/mongoengine/__init__.py +++ b/mongoengine/__init__.py @@ -14,7 +14,7 @@ import errors __all__ = (list(document.__all__) + fields.__all__ + connection.__all__ + list(queryset.__all__) + signals.__all__ + list(errors.__all__)) -VERSION = (0, 10, 4) +VERSION = (0, 10, 5) def get_version(): diff --git a/mongoengine/document.py b/mongoengine/document.py index e27b8eb9..d76c393b 100644 --- a/mongoengine/document.py +++ b/mongoengine/document.py @@ -604,11 +604,16 @@ class Document(BaseDocument): if not fields or field in fields: try: setattr(self, field, self._reload(field, obj[field])) - except KeyError: - # If field is removed from the database while the object - # is in memory, a reload would cause a KeyError - # i.e. obj.update(unset__field=1) followed by obj.reload() - delattr(self, field) + except (KeyError, AttributeError): + try: + # If field is a special field, e.g. items is stored as _reserved_items, + # an KeyError is thrown. So try to retrieve the field from _data + setattr(self, field, self._reload(field, obj._data.get(field))) + except KeyError: + # If field is removed from the database while the object + # is in memory, a reload would cause a KeyError + # i.e. obj.update(unset__field=1) followed by obj.reload() + delattr(self, field) self._changed_fields = obj._changed_fields self._created = False diff --git a/tests/document/instance.py b/tests/document/instance.py index 5494ac6b..deb4e6ac 100644 --- a/tests/document/instance.py +++ b/tests/document/instance.py @@ -571,6 +571,28 @@ class InstanceTest(unittest.TestCase): except Exception: self.assertFalse("Threw wrong exception") + def test_reload_of_non_strict_with_special_field_name(self): + """Ensures reloading works for documents with meta strict == False + """ + class Post(Document): + meta = { + 'strict': False + } + title = StringField() + items = ListField() + + Post.drop_collection() + + Post._get_collection().insert_one({ + "title": "Items eclipse", + "items": ["more lorem", "even more ipsum"] + }) + + post = Post.objects.first() + post.reload() + self.assertEqual(post.title, "Items eclipse") + self.assertEqual(post.items, ["more lorem", "even more ipsum"]) + def test_dictionary_access(self): """Ensure that dictionary-style field access works properly. """