summaryrefslogtreecommitdiff
path: root/tests/composite_pk
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2025-01-27 23:10:13 -0500
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-02-11 09:08:35 +0100
commit41239fe34d64e801212dccaa4585e4802d0fac68 (patch)
tree5a7375f6945d53932f682fa894dd856d22129327 /tests/composite_pk
parent0597e8ad1e55b565292ead732916aa0e39bdf37b (diff)
Fixed #36149 -- Allowed subquery values against tuple exact and in lookups.
Non-tuple exact and in lookups have specialized logic for subqueries that can be adapted to properly assign select mask if unspecified and ensure the number of involved members are matching on both side of the operator.
Diffstat (limited to 'tests/composite_pk')
-rw-r--r--tests/composite_pk/models/tenant.py1
-rw-r--r--tests/composite_pk/test_filter.py58
-rw-r--r--tests/composite_pk/tests.py9
3 files changed, 57 insertions, 11 deletions
diff --git a/tests/composite_pk/models/tenant.py b/tests/composite_pk/models/tenant.py
index 6286ed2354..c85869afa7 100644
--- a/tests/composite_pk/models/tenant.py
+++ b/tests/composite_pk/models/tenant.py
@@ -44,6 +44,7 @@ class Comment(models.Model):
related_name="comments",
)
text = models.TextField(default="", blank=True)
+ integer = models.IntegerField(default=0)
class Post(models.Model):
diff --git a/tests/composite_pk/test_filter.py b/tests/composite_pk/test_filter.py
index fe942b9e5b..d4c6ef13e0 100644
--- a/tests/composite_pk/test_filter.py
+++ b/tests/composite_pk/test_filter.py
@@ -10,7 +10,7 @@ from django.db.models import (
)
from django.db.models.functions import Cast
from django.db.models.lookups import Exact
-from django.test import TestCase
+from django.test import TestCase, skipUnlessDBFeature
from .models import Comment, Tenant, User
@@ -182,6 +182,30 @@ class CompositePKFilterTests(TestCase):
Comment.objects.filter(pk__in=pks).order_by("pk"), objs
)
+ def test_filter_comments_by_pk_in_subquery(self):
+ self.assertSequenceEqual(
+ Comment.objects.filter(
+ pk__in=Comment.objects.filter(pk=self.comment_1.pk),
+ ),
+ [self.comment_1],
+ )
+ self.assertSequenceEqual(
+ Comment.objects.filter(
+ pk__in=Comment.objects.filter(pk=self.comment_1.pk).values(
+ "tenant_id", "id"
+ ),
+ ),
+ [self.comment_1],
+ )
+ self.comment_2.integer = self.comment_1.id
+ self.comment_2.save()
+ self.assertSequenceEqual(
+ Comment.objects.filter(
+ pk__in=Comment.objects.values("tenant_id", "integer"),
+ ),
+ [self.comment_1],
+ )
+
def test_filter_comments_by_user_and_order_by_pk_asc(self):
self.assertSequenceEqual(
Comment.objects.filter(user=self.user_1).order_by("pk"),
@@ -440,16 +464,40 @@ class CompositePKFilterTests(TestCase):
queryset = Comment.objects.filter(**{f"id{lookup}": subquery})
self.assertEqual(queryset.count(), expected_count)
- def test_non_outer_ref_subquery(self):
- # If rhs is any non-OuterRef object with an as_sql() function.
+ def test_unsupported_rhs(self):
pk = Exact(F("tenant_id"), 1)
msg = (
- "'exact' subquery lookup of 'pk' only supports OuterRef objects "
- "(received 'Exact')"
+ "'exact' subquery lookup of 'pk' only supports OuterRef "
+ "and QuerySet objects (received 'Exact')"
)
with self.assertRaisesMessage(ValueError, msg):
Comment.objects.filter(pk=pk)
+ @skipUnlessDBFeature("allow_sliced_subqueries_with_in")
+ def test_filter_comments_by_pk_exact_subquery(self):
+ self.assertSequenceEqual(
+ Comment.objects.filter(
+ pk=Comment.objects.filter(pk=self.comment_1.pk)[:1],
+ ),
+ [self.comment_1],
+ )
+ self.assertSequenceEqual(
+ Comment.objects.filter(
+ pk__in=Comment.objects.filter(pk=self.comment_1.pk).values(
+ "tenant_id", "id"
+ )[:1],
+ ),
+ [self.comment_1],
+ )
+ self.comment_2.integer = self.comment_1.id
+ self.comment_2.save()
+ self.assertSequenceEqual(
+ Comment.objects.filter(
+ pk__in=Comment.objects.values("tenant_id", "integer"),
+ )[:1],
+ [self.comment_1],
+ )
+
def test_outer_ref_not_composite_pk(self):
subquery = Comment.objects.filter(pk=OuterRef("id")).values("id")
queryset = Comment.objects.filter(id=Subquery(subquery))
diff --git a/tests/composite_pk/tests.py b/tests/composite_pk/tests.py
index 6b09480fb0..18fa53d9c0 100644
--- a/tests/composite_pk/tests.py
+++ b/tests/composite_pk/tests.py
@@ -109,13 +109,10 @@ class CompositePKTests(TestCase):
def test_composite_pk_in_fields(self):
user_fields = {f.name for f in User._meta.get_fields()}
- self.assertEqual(user_fields, {"pk", "tenant", "id", "email", "comments"})
+ self.assertTrue({"pk", "tenant", "id"}.issubset(user_fields))
comment_fields = {f.name for f in Comment._meta.get_fields()}
- self.assertEqual(
- comment_fields,
- {"pk", "tenant", "id", "user_id", "user", "text"},
- )
+ self.assertTrue({"pk", "tenant", "id"}.issubset(comment_fields))
def test_pk_field(self):
pk = User._meta.get_field("pk")
@@ -174,7 +171,7 @@ class CompositePKTests(TestCase):
self.assertEqual(user.email, self.user.email)
def test_model_forms(self):
- fields = ["tenant", "id", "user_id", "text"]
+ fields = ["tenant", "id", "user_id", "text", "integer"]
self.assertEqual(list(CommentForm.base_fields), fields)
form = modelform_factory(Comment, fields="__all__")