diff options
| author | Simon Charette <charette.s@gmail.com> | 2025-01-27 23:10:13 -0500 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2025-02-11 09:08:35 +0100 |
| commit | 41239fe34d64e801212dccaa4585e4802d0fac68 (patch) | |
| tree | 5a7375f6945d53932f682fa894dd856d22129327 /tests/composite_pk | |
| parent | 0597e8ad1e55b565292ead732916aa0e39bdf37b (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.py | 1 | ||||
| -rw-r--r-- | tests/composite_pk/test_filter.py | 58 | ||||
| -rw-r--r-- | tests/composite_pk/tests.py | 9 |
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__") |
