summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
Diffstat (limited to 'django')
-rw-r--r--django/db/models/expressions.py15
1 files changed, 14 insertions, 1 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 3adec334f7..2733fbada9 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -6,6 +6,7 @@ from decimal import Decimal
from django.core.exceptions import EmptyResultSet, FieldError
from django.db import connection
from django.db.models import fields
+from django.db.models.constants import LOOKUP_SEP
from django.db.models.query_utils import Q
from django.db.utils import NotSupportedError
from django.utils.deconstruct import deconstructible
@@ -558,6 +559,14 @@ class ResolvedOuterRef(F):
'only be used in a subquery.'
)
+ def resolve_expression(self, *args, **kwargs):
+ col = super().resolve_expression(*args, **kwargs)
+ # FIXME: Rename possibly_multivalued to multivalued and fix detection
+ # for non-multivalued JOINs (e.g. foreign key fields). This should take
+ # into account only many-to-many and one-to-many relationships.
+ col.possibly_multivalued = LOOKUP_SEP in self.name
+ return col
+
def relabeled_clone(self, relabels):
return self
@@ -744,6 +753,7 @@ class Random(Expression):
class Col(Expression):
contains_column_references = True
+ possibly_multivalued = False
def __init__(self, alias, target, output_field=None):
if output_field is None:
@@ -1068,7 +1078,10 @@ class Subquery(Expression):
def get_group_by_cols(self, alias=None):
if alias:
return [Ref(alias, self)]
- return self.query.get_external_cols()
+ external_cols = self.query.get_external_cols()
+ if any(col.possibly_multivalued for col in external_cols):
+ return [self]
+ return external_cols
class Exists(Subquery):