Merge pull request #1117 from reallistic/master

Enable ops in queries using elemMatch for EmbeddedDocuments
fixes #1130
This commit is contained in:
David Bordeynik 2015-10-21 08:40:39 +03:00
commit 2f1fae38dd
3 changed files with 23 additions and 8 deletions

View File

@ -11,6 +11,7 @@ Changes in 0.10.1 - DEV
- Fix Document.reload for DynamicDocument. #1050
- StrictDict & SemiStrictDict are shadowed at init time. #1105
- Remove test dependencies (nose and rednose) from install dependencies list. #1079
- Recursively build query when using elemMatch operator. #1130
Changes in 0.10.0
=================

View File

@ -26,12 +26,12 @@ MATCH_OPERATORS = (COMPARISON_OPERATORS + GEO_OPERATORS +
STRING_OPERATORS + CUSTOM_OPERATORS)
def query(_doc_cls=None, **query):
def query(_doc_cls=None, **kwargs):
"""Transform a query from Django-style format to Mongo format.
"""
mongo_query = {}
merge_query = defaultdict(list)
for key, value in sorted(query.items()):
for key, value in sorted(kwargs.items()):
if key == "__raw__":
mongo_query.update(value)
continue
@ -105,11 +105,16 @@ def query(_doc_cls=None, **query):
if op:
if op in GEO_OPERATORS:
value = _geo_operator(field, op, value)
elif op in CUSTOM_OPERATORS:
if op in ('elem_match', 'match'):
elif op in ('match', 'elemMatch'):
ListField = _import_class('ListField')
EmbeddedDocumentField = _import_class('EmbeddedDocumentField')
if (isinstance(value, dict) and isinstance(field, ListField) and
isinstance(field.field, EmbeddedDocumentField)):
value = query(field.field.document_type, **value)
else:
value = field.prepare_query_value(op, value)
value = {"$elemMatch": value}
else:
elif op in CUSTOM_OPERATORS:
NotImplementedError("Custom method '%s' has not "
"been implemented" % op)
elif op not in STRING_OPERATORS:

View File

@ -4116,6 +4116,15 @@ class QuerySetTest(unittest.TestCase):
ak = list(Bar.objects(foo__match=Foo(shape="square", color="purple")))
self.assertEqual([b1], ak)
ak = list(
Bar.objects(foo__elemMatch={'shape': "square", "color__exists": True}))
self.assertEqual([b1, b2], ak)
ak = list(
Bar.objects(foo__match={'shape': "square", "color__exists": True}))
self.assertEqual([b1, b2], ak)
def test_upsert_includes_cls(self):
"""Upserts should include _cls information for inheritable classes
"""