From 6d7a2df39071b244089dee41f363094f59979d0f Mon Sep 17 00:00:00 2001 From: HuangYan Date: Wed, 2 Oct 2019 17:59:39 +0800 Subject: [PATCH 1/4] add case test db_field conflict --- tests/document/test_instance.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/document/test_instance.py b/tests/document/test_instance.py index 9b4a16e5a..5999f24b4 100644 --- a/tests/document/test_instance.py +++ b/tests/document/test_instance.py @@ -297,6 +297,31 @@ def rank(self): self.assertEqual(Person.objects.get(name="Jack").rank, "Corporal") self.assertEqual(Person.objects.get(name="Fred").rank, "Private") + def test_db_field_conflict(self): + """Ensure we load data correctly from the right db field.""" + + class Person(Document): + name = StringField(required=True) + age = IntField(required=False, db_field="gregorian_age") + lunar_age = IntField(required=False, db_field="age") + # in 0.18.2 version, remove db_field this will run correct + # age = IntField(required=False) + # lunar_age = IntField(required=False) + + Person.drop_collection() + p = Person(name="Jack", age="18", lunar_age="20") + + self.assertEqual(p._data, {'age': 18, 'id': None, 'name': u'Jack', 'lunar_age': 20}) + self.assertEqual(p.to_mongo(), bson.SON([('name', u'Jack'), ('gregorian_age', 18), ('age', 20)])) + + + Person(name="Jack", age="18", lunar_age="20").save() + Person(name="Fred", age="28", lunar_age="30").save() + + p = Person.objects.get(name="Jack") + self.assertEqual(p.age, 18) + self.assertEqual(Person.objects.get(name="Fred").lunar_age, 30) + def test_db_embedded_doc_field_load(self): """Ensure we load embedded document data correctly.""" From f240aabb776b87e59d2bde51983663ea296ce609 Mon Sep 17 00:00:00 2001 From: HuangYan Date: Wed, 2 Oct 2019 19:31:26 +0800 Subject: [PATCH 2/4] Fix db_field conflict bug --- mongoengine/base/document.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index a962a82b6..e157c9f34 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -81,9 +81,7 @@ def __init__(self, *args, **values): ) __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) @@ -130,7 +128,6 @@ def __init__(self, *args, **values): else: FileField = _import_class("FileField") for key, value in iteritems(values): - key = self._reverse_db_field_map.get(key, key) if key in self._fields or key in ("id", "pk", "_cls"): if __auto_convert and value is not None: field = self._fields.get(key) @@ -743,7 +740,6 @@ def _from_son(cls, son, _auto_dereference=True, only_fields=None, created=False) data = {} for key, value in iteritems(son): key = str(key) - key = cls._db_field_map.get(key, key) data[key] = value # Return correct subclass for document type @@ -756,19 +752,25 @@ def _from_son(cls, son, _auto_dereference=True, only_fields=None, created=False) if not _auto_dereference: fields = copy.deepcopy(fields) + _conflict_cached_data = {} for field_name, field in iteritems(fields): field._auto_dereference = _auto_dereference if field.db_field in data: value = data[field.db_field] try: - data[field_name] = ( - value if value is None else field.to_python(value) - ) + if field_name in data: + _conflict_cached_data[field_name] = ( + value if value is None else field.to_python(value) + ) + else: + data[field_name] = ( + value if value is None else field.to_python(value) + ) if field_name != field.db_field: del data[field.db_field] except (AttributeError, ValueError) as e: errors_dict[field_name] = e - + data.update(_conflict_cached_data) if errors_dict: errors = "\n".join(["%s - %s" % (k, v) for k, v in errors_dict.items()]) msg = "Invalid data to create a `%s` instance.\n%s" % ( From 2c8c1c7818bd8667a95316700e0c6230e2229fe3 Mon Sep 17 00:00:00 2001 From: HuangYan Date: Sat, 5 Oct 2019 16:48:46 +0800 Subject: [PATCH 3/4] fix error test case --- tests/fields/test_fields.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/fields/test_fields.py b/tests/fields/test_fields.py index d9279c22e..11623cf12 100644 --- a/tests/fields/test_fields.py +++ b/tests/fields/test_fields.py @@ -1224,7 +1224,10 @@ class A(Document): a = A(b=B(c=C(txt="hi"))) a.validate() - a = A(b={"c": {"txt": "hi"}}) + a = A(b=B(c={"txt": "hi"})) + a.validate() + + a = A(b={"fc": {"txt": "hi"}}) a.validate() def test_double_embedded_db_field_from_son(self): From d62f3a39bf2bcbd45dc478b3c0491202aee87e6c Mon Sep 17 00:00:00 2001 From: HuangYan Date: Sat, 5 Oct 2019 18:10:03 +0800 Subject: [PATCH 4/4] reformat code --- tests/document/test_instance.py | 40 +++++++++++++-------------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/tests/document/test_instance.py b/tests/document/test_instance.py index 5999f24b4..381db33f0 100644 --- a/tests/document/test_instance.py +++ b/tests/document/test_instance.py @@ -298,15 +298,12 @@ def rank(self): self.assertEqual(Person.objects.get(name="Fred").rank, "Private") def test_db_field_conflict(self): - """Ensure we load data correctly from the right db field.""" + """Ensure two db field will not conflict.""" class Person(Document): name = StringField(required=True) age = IntField(required=False, db_field="gregorian_age") lunar_age = IntField(required=False, db_field="age") - # in 0.18.2 version, remove db_field this will run correct - # age = IntField(required=False) - # lunar_age = IntField(required=False) Person.drop_collection() p = Person(name="Jack", age="18", lunar_age="20") @@ -314,8 +311,8 @@ class Person(Document): self.assertEqual(p._data, {'age': 18, 'id': None, 'name': u'Jack', 'lunar_age': 20}) self.assertEqual(p.to_mongo(), bson.SON([('name', u'Jack'), ('gregorian_age', 18), ('age', 20)])) - Person(name="Jack", age="18", lunar_age="20").save() + Person(name="Fred", age="28", lunar_age="30").save() p = Person.objects.get(name="Jack") @@ -376,7 +373,6 @@ class User(Document): meta = {"allow_inheritance": True} with self.assertRaises(ValueError) as e: - class EmailUser(User): email = StringField(primary_key=True) @@ -775,8 +771,8 @@ class Doc(Document): d = ( Doc(embedded_field=[Embedded(string="Hi")]) - .to_mongo(use_db_field=False) - .to_dict() + .to_mongo(use_db_field=False) + .to_dict() ) self.assertEqual(d["embedded_field"], [{"string": "Hi"}]) @@ -1640,7 +1636,7 @@ class User(self.Person): self.assertEqual(person.active, False) def test__get_changed_fields_same_ids_reference_field_does_not_enters_infinite_loop_embedded_doc( - self + self ): # Refers to Issue #1685 class EmbeddedChildModel(EmbeddedDocument): @@ -1654,7 +1650,7 @@ class ParentModel(Document): self.assertEqual(changed_fields, []) def test__get_changed_fields_same_ids_reference_field_does_not_enters_infinite_loop_different_doc( - self + self ): # Refers to Issue #1685 class User(Document): @@ -2133,7 +2129,6 @@ def test_duplicate_db_fields_raise_invalid_document_error(self): declare the same db_field. """ with self.assertRaises(InvalidDocumentError): - class Foo(Document): name = StringField() name2 = StringField(db_field="name") @@ -2419,7 +2414,6 @@ class Foo(Document): def test_invalid_reverse_delete_rule_raise_errors(self): with self.assertRaises(InvalidDocumentError): - class Blog(Document): content = StringField() authors = MapField( @@ -2430,7 +2424,6 @@ class Blog(Document): ) with self.assertRaises(InvalidDocumentError): - class Parents(EmbeddedDocument): father = ReferenceField("Person", reverse_delete_rule=DENY) mother = ReferenceField("Person", reverse_delete_rule=DENY) @@ -2668,7 +2661,6 @@ def test_override_method_with_field(self): the "validate" method. """ with self.assertRaises(InvalidDocumentError): - class Blog(Document): validate = DictField() @@ -2932,8 +2924,8 @@ def __str__(self): [ str(b) for b in Book.objects.filter( - Q(extra__a=bob) | Q(author=bob) | Q(extra__b=bob) - ) + Q(extra__a=bob) | Q(author=bob) | Q(extra__b=bob) + ) ] ), "1,2,3,4", @@ -2945,10 +2937,10 @@ def __str__(self): [ str(b) for b in Book.objects.filter( - Q(extra__a__all=[karl, susan]) - | Q(author__all=[karl, susan]) - | Q(extra__b__all=[karl.to_dbref(), susan.to_dbref()]) - ) + Q(extra__a__all=[karl, susan]) + | Q(author__all=[karl, susan]) + | Q(extra__b__all=[karl.to_dbref(), susan.to_dbref()]) + ) ] ), "1", @@ -2960,13 +2952,13 @@ def __str__(self): [ str(b) for b in Book.objects.filter( - __raw__={ - "$where": """ + __raw__={ + "$where": """ function(){ return this.name == '1' || this.name == '2';}""" - } - ) + } + ) ] ), "1,2",