From 8fd969aba912520900f0c0df807dc31a44233df0 Mon Sep 17 00:00:00 2001 From: Jan Stein Date: Wed, 3 Mar 2021 14:58:03 +0100 Subject: [PATCH] Test case and proposed solution for #2484 --- AUTHORS | 1 + docs/changelog.rst | 1 + mongoengine/base/document.py | 10 +++++++++- tests/fields/test_lazy_reference_field.py | 20 ++++++++++++++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 1cf7d78a..0c7f6b46 100644 --- a/AUTHORS +++ b/AUTHORS @@ -259,3 +259,4 @@ that much better: * Agustin Barto (https://github.com/abarto) * Stankiewicz Mateusz (https://github.com/mas15) * Felix Schultheiß (https://github.com/felix-smashdocs) + * Jan Stein (https://github.com/janste63) diff --git a/docs/changelog.rst b/docs/changelog.rst index 5898eb1f..e647081e 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -7,6 +7,7 @@ Development =========== - (Fill this out as you fix issues and develop your features). - Bugfix: manually setting SequenceField in DynamicDocument doesn't increment the counter #2471 +- Bug fix: ignore LazyReferenceFields when clearing _changed_fields #2484 Changes in 0.22.1 ================= diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 34409562..b76671ce 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -615,7 +615,9 @@ class BaseDocument: def _get_changed_fields(self): """Return a list of all fields that have explicitly been changed.""" EmbeddedDocument = _import_class("EmbeddedDocument") + LazyReferenceField = _import_class("LazyReferenceField") ReferenceField = _import_class("ReferenceField") + GenericLazyReferenceField = _import_class("GenericLazyReferenceField") GenericReferenceField = _import_class("GenericReferenceField") SortedListField = _import_class("SortedListField") @@ -641,7 +643,13 @@ class BaseDocument: changed_fields += [f"{key}{k}" for k in changed if k] elif isinstance(data, (list, tuple, dict)): if hasattr(field, "field") and isinstance( - field.field, (ReferenceField, GenericReferenceField) + field.field, + ( + LazyReferenceField, + ReferenceField, + GenericLazyReferenceField, + GenericReferenceField, + ), ): continue elif isinstance(field, SortedListField) and field._ordering: diff --git a/tests/fields/test_lazy_reference_field.py b/tests/fields/test_lazy_reference_field.py index fd623bfc..2b02668c 100644 --- a/tests/fields/test_lazy_reference_field.py +++ b/tests/fields/test_lazy_reference_field.py @@ -375,6 +375,26 @@ class TestLazyReferenceField(MongoDBTestCase): assert isinstance(ref.author, LazyReference) assert isinstance(ref.author.id, ObjectId) + def test_lazy_reference_in_list_with_changed_element(self): + class Animal(Document): + name = StringField() + tag = StringField() + + class Ocurrence(Document): + in_list = ListField(LazyReferenceField(Animal)) + + Animal.drop_collection() + Ocurrence.drop_collection() + + animal1 = Animal(name="doggo").save() + + animal1.tag = "blue" + + occ = Ocurrence(in_list=[animal1]).save() + animal1.save() + assert isinstance(occ.in_list[0], LazyReference) + assert occ.in_list[0].pk == animal1.pk + class TestGenericLazyReferenceField(MongoDBTestCase): def test_generic_lazy_reference_simple(self):