summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2025-07-24 15:18:47 -0400
committerNatalia <124304+nessita@users.noreply.github.com>2025-07-28 16:40:08 -0300
commit3031c512f0cf030dc8f99128bcb4fb9d4d6e285a (patch)
tree8692964a018a71f0346737866f43e854075b63dd
parent28f33f50b2edb6a40bb2696af0eed2b9d76494cd (diff)
[5.2.x] Fixed #36522 -- Added support for filtering composite pks using a tuple of expressions.
Thanks Jacob Walls for the report, and Sarah Boyce and Mariusz Felisiak for reviews. Backport of 0a4999b422702c64e21f5a10a4d60300b7074401 from main.
-rw-r--r--django/db/models/fields/tuple_lookups.py12
-rw-r--r--docs/releases/5.2.5.txt3
-rw-r--r--tests/composite_pk/test_filter.py8
3 files changed, 21 insertions, 2 deletions
diff --git a/django/db/models/fields/tuple_lookups.py b/django/db/models/fields/tuple_lookups.py
index 2af2e193d5..3b9ff85dff 100644
--- a/django/db/models/fields/tuple_lookups.py
+++ b/django/db/models/fields/tuple_lookups.py
@@ -92,7 +92,11 @@ class TupleLookupMixin:
def process_rhs(self, compiler, connection):
if self.rhs_is_direct_value():
args = [
- Value(val, output_field=col.output_field)
+ (
+ val
+ if hasattr(val, "as_sql")
+ else Value(val, output_field=col.output_field)
+ )
for col, val in zip(self.lhs, self.rhs)
]
return compiler.compile(Tuple(*args))
@@ -326,7 +330,11 @@ class TupleIn(TupleLookupMixin, In):
result.append(
Tuple(
*[
- Value(val, output_field=col.output_field)
+ (
+ val
+ if hasattr(val, "as_sql")
+ else Value(val, output_field=col.output_field)
+ )
for col, val in zip(lhs, vals)
]
)
diff --git a/docs/releases/5.2.5.txt b/docs/releases/5.2.5.txt
index a72a3fe078..7708563857 100644
--- a/docs/releases/5.2.5.txt
+++ b/docs/releases/5.2.5.txt
@@ -12,3 +12,6 @@ Bugfixes
* Fixed a regression in Django 5.2.1 that prevented the usage of ``UNNEST``
PostgreSQL strategy of ``QuerySet.bulk_create()`` with foreign keys
(:ticket:`36502`).
+
+* Fixed a crash in Django 5.2 when filtering against a composite primary key
+ using a tuple containing expressions (:ticket:`36522`).
diff --git a/tests/composite_pk/test_filter.py b/tests/composite_pk/test_filter.py
index 03037d4d82..ed6caf8034 100644
--- a/tests/composite_pk/test_filter.py
+++ b/tests/composite_pk/test_filter.py
@@ -9,6 +9,7 @@ from django.db.models import (
Q,
Subquery,
TextField,
+ Value,
When,
)
from django.db.models.functions import Cast
@@ -549,6 +550,13 @@ class CompositePKFilterTests(TestCase):
[self.tenant_1],
)
+ def test_filter_by_tuple_containing_expression(self):
+ pk_lookup = (self.comment_1.tenant.id, (Value(self.comment_1.id) + 1) - 1)
+ for lookup in ({"pk": pk_lookup}, {"pk__in": [pk_lookup]}):
+ with self.subTest(lookup=lookup):
+ qs = Comment.objects.filter(**lookup)
+ self.assertEqual(qs.get(), self.comment_1)
+
@skipUnlessDBFeature("supports_tuple_lookups")
class CompositePKFilterTupleLookupFallbackTests(CompositePKFilterTests):