Merge pull request #1035 from MRigal/fix/882-dynamic-lookup-more-than-two-parts
Simplified lookup_field mechanic and allow dynamic lookup for more than two parts
This commit is contained in:
commit
5badb9d151
@ -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
|
||||
================
|
||||
|
@ -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)
|
||||
elif not new_field:
|
||||
raise LookUpError('Cannot resolve field "%s"'
|
||||
% field_name)
|
||||
|
@ -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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user