From 49c0c9f44ca0fb01ed14a3ff390f6666b9303385 Mon Sep 17 00:00:00 2001 From: Matthieu Rigal Date: Sun, 21 Jun 2015 01:37:25 +0200 Subject: [PATCH 1/2] Simplified lookup-field method, allowing dynamic lookup for more than two parts --- mongoengine/base/document.py | 20 ++++++-------------- tests/document/dynamic.py | 9 +++++++++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 1049eabd..73939fa9 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -935,6 +935,7 @@ class BaseDocument(object): """ ListField = _import_class("ListField") + DynamicField = _import_class('DynamicField') if not isinstance(parts, (list, tuple)): parts = [parts] @@ -944,7 +945,6 @@ class BaseDocument(object): for field_name in parts: # Handle ListField indexing: if field_name.isdigit() and isinstance(field, ListField): - new_field = field.field fields.append(field_name) continue @@ -956,11 +956,9 @@ class BaseDocument(object): if field_name in cls._fields: field = cls._fields[field_name] elif cls._dynamic: - DynamicField = _import_class('DynamicField') field = DynamicField(db_field=field_name) elif cls._meta.get("allow_inheritance", False) or cls._meta.get("abstract", False): # 744: in case the field is defined in a subclass - field = None for subcls in cls.__subclasses__(): try: field = subcls._lookup_field([field_name])[0] @@ -982,6 +980,9 @@ class BaseDocument(object): '__'.join(parts)) if hasattr(getattr(field, 'field', None), 'lookup_member'): new_field = field.field.lookup_member(field_name) + elif cls._dynamic and (isinstance(field, DynamicField) or + getattr(getattr(field, 'document_type'), '_dynamic')): + new_field = DynamicField(db_field=field_name) else: # Look up subfield on the previous field or raise try: @@ -991,17 +992,8 @@ class BaseDocument(object): 'on the field {}'.format( field_name, field.name)) if not new_field and isinstance(field, ComplexBaseField): - if hasattr(field.field, 'document_type') and cls._dynamic \ - and field.field.document_type._dynamic: - DynamicField = _import_class('DynamicField') - new_field = DynamicField(db_field=field_name) - else: - fields.append(field_name) - continue - elif not new_field and hasattr(field, 'document_type') and cls._dynamic \ - and field.document_type._dynamic: - DynamicField = _import_class('DynamicField') - new_field = DynamicField(db_field=field_name) + fields.append(field_name) + continue elif not new_field: raise LookUpError('Cannot resolve field "%s"' % field_name) diff --git a/tests/document/dynamic.py b/tests/document/dynamic.py index 52136efc..b2947df4 100644 --- a/tests/document/dynamic.py +++ b/tests/document/dynamic.py @@ -129,6 +129,15 @@ class DynamicTest(unittest.TestCase): self.assertEqual(1, self.Person.objects(misc__hello='world').count()) + def test_three_level_complex_data_lookups(self): + """Ensure you can query three level document dynamic fields""" + p = self.Person() + p.misc = {'hello': {'hello2': 'world'}} + p.save() + # from pprint import pprint as pp; import pdb; pdb.set_trace(); + print self.Person.objects(misc__hello__hello2='world') + self.assertEqual(1, self.Person.objects(misc__hello__hello2='world').count()) + def test_complex_embedded_document_validation(self): """Ensure embedded dynamic documents may be validated""" class Embedded(DynamicEmbeddedDocument): From 45dc379d9a3a7e4600d30435b91fb6dcab9b2af3 Mon Sep 17 00:00:00 2001 From: Matthieu Rigal Date: Sun, 21 Jun 2015 01:39:10 +0200 Subject: [PATCH 2/2] Added to changelog --- docs/changelog.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 6bff946d..0dcd1e08 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -28,6 +28,7 @@ Changes in 0.9.X - DEV - Capped collection multiple of 256. #1011 - Added `BaseQuerySet.aggregate_sum` and `BaseQuerySet.aggregate_average` methods. - Fix for delete with write_concern {'w': 0}. #1008 +- Allow dynamic lookup for more than two parts. #882 Changes in 0.9.0 ================