From d8b8ff68517c851bdedcd584a0511a47087f4755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastien=20G=C3=A9rard?= Date: Mon, 2 Nov 2020 14:52:02 +0100 Subject: [PATCH 1/2] Removed code related to Document.__only_fields and Queryset.only_fields which appear to have no effect --- docs/changelog.rst | 1 + mongoengine/base/document.py | 15 +++------------ mongoengine/queryset/base.py | 34 ++++++++------------------------- tests/document/test_instance.py | 2 +- 4 files changed, 13 insertions(+), 39 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index f63edc61..3a9cbd5f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -14,6 +14,7 @@ Development - Bug fix in ListField when updating the first item, it was saving the whole list, instead of just replacing the first item (as it's usually done) #2392 - Add EnumField: ``mongoengine.fields.EnumField`` +- Refactoring - Remove useless code related to Document.__only_fields and Queryset.only_fields Changes in 0.20.0 ================= diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 8b0ab91f..0fd88035 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -64,8 +64,6 @@ class BaseDocument: It may contain additional reserved keywords, e.g. "__auto_convert". :param __auto_convert: If True, supplied values will be converted to Python-type values via each field's `to_python` method. - :param __only_fields: A set of fields that have been loaded for - this document. Empty if all fields have been loaded. :param _created: Indicates whether this is a brand new document or whether it's already been persisted before. Defaults to true. """ @@ -80,8 +78,6 @@ class BaseDocument: __auto_convert = values.pop("__auto_convert", True) - __only_fields = set(values.pop("__only_fields", values)) - _created = values.pop("_created", True) signals.pre_init.send(self.__class__, document=self, values=values) @@ -109,7 +105,7 @@ class BaseDocument: # We set default values only for fields loaded from DB. See # https://github.com/mongoengine/mongoengine/issues/399 for more info. for key, field in self._fields.items(): - if self._db_field_map.get(key, key) in __only_fields: + if self._db_field_map.get(key, key) in values: continue value = getattr(self, key, None) setattr(self, key, value) @@ -758,11 +754,8 @@ class BaseDocument: return cls._meta.get("collection", None) @classmethod - def _from_son(cls, son, _auto_dereference=True, only_fields=None, created=False): + def _from_son(cls, son, _auto_dereference=True, created=False): """Create an instance of a Document (subclass) from a PyMongo SON.""" - if not only_fields: - only_fields = [] - if son and not isinstance(son, dict): raise ValueError( "The source SON object needs to be of type 'dict' but a '%s' was found" @@ -817,9 +810,7 @@ class BaseDocument: if cls.STRICT: data = {k: v for k, v in data.items() if k in cls._fields} - obj = cls( - __auto_convert=False, _created=created, __only_fields=only_fields, **data - ) + obj = cls(__auto_convert=False, _created=created, **data) obj._changed_fields = [] if not _auto_dereference: obj._fields = fields diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index 33ab6e2a..1021bf5e 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -88,7 +88,6 @@ class BaseQuerySet: self._hint = -1 # Using -1 as None is a valid value for hint self._collation = None self._batch_size = None - self.only_fields = [] self._max_time_ms = None self._comment = None @@ -190,9 +189,7 @@ class BaseQuerySet: if queryset._scalar: return queryset._get_scalar( queryset._document._from_son( - queryset._cursor[key], - _auto_dereference=self._auto_dereference, - only_fields=self.only_fields, + queryset._cursor[key], _auto_dereference=self._auto_dereference, ) ) @@ -200,9 +197,7 @@ class BaseQuerySet: return queryset._cursor[key] return queryset._document._from_son( - queryset._cursor[key], - _auto_dereference=self._auto_dereference, - only_fields=self.only_fields, + queryset._cursor[key], _auto_dereference=self._auto_dereference, ) raise TypeError("Provide a slice or an integer index") @@ -719,12 +714,10 @@ class BaseQuerySet: if full_response: if result["value"] is not None: - result["value"] = self._document._from_son( - result["value"], only_fields=self.only_fields - ) + result["value"] = self._document._from_son(result["value"]) else: if result is not None: - result = self._document._from_son(result, only_fields=self.only_fields) + result = self._document._from_son(result) return result @@ -757,18 +750,14 @@ class BaseQuerySet: docs = self._collection.find({"_id": {"$in": object_ids}}, **self._cursor_args) if self._scalar: for doc in docs: - doc_map[doc["_id"]] = self._get_scalar( - self._document._from_son(doc, only_fields=self.only_fields) - ) + doc_map[doc["_id"]] = self._get_scalar(self._document._from_son(doc)) elif self._as_pymongo: for doc in docs: doc_map[doc["_id"]] = doc else: for doc in docs: doc_map[doc["_id"]] = self._document._from_son( - doc, - only_fields=self.only_fields, - _auto_dereference=self._auto_dereference, + doc, _auto_dereference=self._auto_dereference, ) return doc_map @@ -841,7 +830,6 @@ class BaseQuerySet: "_collation", "_auto_dereference", "_search_text", - "only_fields", "_max_time_ms", "_comment", "_batch_size", @@ -1045,7 +1033,6 @@ class BaseQuerySet: .. versionchanged:: 0.5 - Added subfield support """ fields = {f: QueryFieldList.ONLY for f in fields} - self.only_fields = list(fields.keys()) return self.fields(True, **fields) def exclude(self, *fields): @@ -1310,10 +1297,7 @@ class BaseQuerySet: def from_json(self, json_data): """Converts json data to unsaved objects""" son_data = json_util.loads(json_data) - return [ - self._document._from_son(data, only_fields=self.only_fields) - for data in son_data - ] + return [self._document._from_son(data) for data in son_data] def aggregate(self, pipeline, *suppl_pipeline, **kwargs): """Perform a aggregate function based in your queryset params @@ -1638,9 +1622,7 @@ class BaseQuerySet: return raw_doc doc = self._document._from_son( - raw_doc, - _auto_dereference=self._auto_dereference, - only_fields=self.only_fields, + raw_doc, _auto_dereference=self._auto_dereference, ) if self._scalar: diff --git a/tests/document/test_instance.py b/tests/document/test_instance.py index 9554659c..960de924 100644 --- a/tests/document/test_instance.py +++ b/tests/document/test_instance.py @@ -3411,7 +3411,7 @@ class TestDocumentInstance(MongoDBTestCase): assert obj3 != dbref2 assert dbref2 != obj3 - def test_default_values(self): + def test_default_values_dont_get_override_upon_save_when_only_is_used(self): class Person(Document): created_on = DateTimeField(default=lambda: datetime.utcnow()) name = StringField() From 90c5d83f8432d97050c21163349d80b1f9b3892b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastien=20G=C3=A9rard?= Date: Mon, 2 Nov 2020 15:02:11 +0100 Subject: [PATCH 2/2] remove deprecated comment --- mongoengine/base/document.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 0fd88035..5b727437 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -102,8 +102,6 @@ class BaseDocument: self._dynamic_fields = SON() # Assign default values to the instance. - # We set default values only for fields loaded from DB. See - # https://github.com/mongoengine/mongoengine/issues/399 for more info. for key, field in self._fields.items(): if self._db_field_map.get(key, key) in values: continue