diff options
| author | Bendeguz Csirmaz <csirmazbendeguz@gmail.com> | 2025-01-07 20:08:25 +0800 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2025-01-10 14:38:09 +0100 |
| commit | 8bee7fa45cd7bfe70b68784314e994e2d193fd70 (patch) | |
| tree | fd0c321ed60210ed96403ec482b57670334b844b /django/db/models/fields/tuple_lookups.py | |
| parent | 97ee8b82c2c99bf352df5359bb24a42ea78585b8 (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.py | 36 |
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): |
