Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Changelog
Development
===========
- (Fill this out as you fix issues and develop your features).
- Fix querying GenericReferenceField with __in operator #2886
- Fix Document.compare_indexes() not working correctly for text indexes on multiple fields #2612
- Add support for transaction through run_in_transaction (kudos to juannyG for this) #2569
Some considerations:
Expand Down
20 changes: 18 additions & 2 deletions mongoengine/queryset/transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,15 @@ def query(_doc_cls=None, **kwargs):

singular_ops = [None, "ne", "gt", "gte", "lt", "lte", "not"]
singular_ops += STRING_OPERATORS
is_iterable = False
if op in singular_ops:
value = field.prepare_query_value(op, value)

if isinstance(field, CachedReferenceField) and value:
value = value["_id"]

elif op in ("in", "nin", "all", "near") and not isinstance(value, dict):
is_iterable = True
# Raise an error if the in/nin/all/near param is not iterable.
value = _prepare_query_for_iterable(field, op, value)

Expand All @@ -144,10 +146,24 @@ def query(_doc_cls=None, **kwargs):
# * If the value is a DBRef, the key should be "field_name._ref".
# * If the value is an ObjectId, the key should be "field_name._ref.$id".
if isinstance(field, GenericReferenceField):
if isinstance(value, DBRef):
if isinstance(value, DBRef) or (
is_iterable and all(isinstance(v, DBRef) for v in value)
):
parts[-1] += "._ref"
elif isinstance(value, ObjectId):
elif isinstance(value, ObjectId) or (
is_iterable and all(isinstance(v, ObjectId) for v in value)
):
parts[-1] += "._ref.$id"
elif (
is_iterable
and any(isinstance(v, DBRef) for v in value)
and any(isinstance(v, ObjectId) for v in value)
):
raise ValueError(
"The `in`, `nin`, `all`, or `near`-operators cannot "
"be applied to mixed queries of DBRef/ObjectId/%s"
% _doc_cls.__name__
)

# if op and op not in COMPARISON_OPERATORS:
if op:
Expand Down
Loading