summaryrefslogtreecommitdiff
path: root/django/db/models/fields/tuple_lookups.py
diff options
context:
space:
mode:
authorBendeguz Csirmaz <csirmazbendeguz@gmail.com>2025-01-07 20:08:25 +0800
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-01-10 14:38:09 +0100
commit8bee7fa45cd7bfe70b68784314e994e2d193fd70 (patch)
treefd0c321ed60210ed96403ec482b57670334b844b /django/db/models/fields/tuple_lookups.py
parent97ee8b82c2c99bf352df5359bb24a42ea78585b8 (diff)
Fixed #36050 -- Added OuterRef support to CompositePrimaryKey.
Diffstat (limited to 'django/db/models/fields/tuple_lookups.py')
-rw-r--r--django/db/models/fields/tuple_lookups.py36
1 files changed, 28 insertions, 8 deletions
diff --git a/django/db/models/fields/tuple_lookups.py b/django/db/models/fields/tuple_lookups.py
index 51432a666b..2f195f25b9 100644
--- a/django/db/models/fields/tuple_lookups.py
+++ b/django/db/models/fields/tuple_lookups.py
@@ -2,7 +2,7 @@ import itertools
from django.core.exceptions import EmptyResultSet
from django.db.models import Field
-from django.db.models.expressions import ColPairs, Func, Value
+from django.db.models.expressions import ColPairs, Func, ResolvedOuterRef, Value
from django.db.models.lookups import (
Exact,
GreaterThan,
@@ -32,8 +32,11 @@ class TupleLookupMixin:
allows_composite_expressions = True
def get_prep_lookup(self):
- self.check_rhs_is_tuple_or_list()
- self.check_rhs_length_equals_lhs_length()
+ if self.rhs_is_direct_value():
+ self.check_rhs_is_tuple_or_list()
+ self.check_rhs_length_equals_lhs_length()
+ else:
+ self.check_rhs_is_outer_ref()
return self.rhs
def check_rhs_is_tuple_or_list(self):
@@ -51,6 +54,15 @@ class TupleLookupMixin:
f"{self.lookup_name!r} lookup of {lhs_str} must have {len_lhs} elements"
)
+ def check_rhs_is_outer_ref(self):
+ if not isinstance(self.rhs, ResolvedOuterRef):
+ lhs_str = self.get_lhs_str()
+ rhs_cls = self.rhs.__class__.__name__
+ raise ValueError(
+ f"{self.lookup_name!r} subquery lookup of {lhs_str} "
+ f"only supports OuterRef objects (received {rhs_cls!r})"
+ )
+
def get_lhs_str(self):
if isinstance(self.lhs, ColPairs):
return repr(self.lhs.field.name)
@@ -70,11 +82,19 @@ class TupleLookupMixin:
return sql, params
def process_rhs(self, compiler, connection):
- values = [
- Value(val, output_field=col.output_field)
- for col, val in zip(self.lhs, self.rhs)
- ]
- return Tuple(*values).as_sql(compiler, connection)
+ if self.rhs_is_direct_value():
+ args = [
+ Value(val, output_field=col.output_field)
+ for col, val in zip(self.lhs, self.rhs)
+ ]
+ return Tuple(*args).as_sql(compiler, connection)
+ else:
+ sql, params = compiler.compile(self.rhs)
+ if not isinstance(self.rhs, ColPairs):
+ raise ValueError(
+ "Composite field lookups only work with composite expressions."
+ )
+ return "(%s)" % sql, params
class TupleExact(TupleLookupMixin, Exact):