mirror of
https://github.com/django/django.git
synced 2025-10-25 06:36:07 +00:00
Fixed #373 -- Added CompositePrimaryKey.
Thanks Lily Foote and Simon Charette for reviews and mentoring this Google Summer of Code 2024 project. Co-authored-by: Simon Charette <charette.s@gmail.com> Co-authored-by: Lily Foote <code@lilyf.org>
This commit is contained in:
committed by
Sarah Boyce
parent
86661f2449
commit
978aae4334
139
tests/composite_pk/test_aggregate.py
Normal file
139
tests/composite_pk/test_aggregate.py
Normal file
@@ -0,0 +1,139 @@
|
||||
from django.db import NotSupportedError
|
||||
from django.db.models import Count, Q
|
||||
from django.test import TestCase
|
||||
|
||||
from .models import Comment, Tenant, User
|
||||
|
||||
|
||||
class CompositePKAggregateTests(TestCase):
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
cls.tenant_1 = Tenant.objects.create()
|
||||
cls.tenant_2 = Tenant.objects.create()
|
||||
cls.user_1 = User.objects.create(
|
||||
tenant=cls.tenant_1,
|
||||
id=1,
|
||||
email="user0001@example.com",
|
||||
)
|
||||
cls.user_2 = User.objects.create(
|
||||
tenant=cls.tenant_1,
|
||||
id=2,
|
||||
email="user0002@example.com",
|
||||
)
|
||||
cls.user_3 = User.objects.create(
|
||||
tenant=cls.tenant_2,
|
||||
id=3,
|
||||
email="user0003@example.com",
|
||||
)
|
||||
cls.comment_1 = Comment.objects.create(id=1, user=cls.user_2, text="foo")
|
||||
cls.comment_2 = Comment.objects.create(id=2, user=cls.user_1, text="bar")
|
||||
cls.comment_3 = Comment.objects.create(id=3, user=cls.user_1, text="foobar")
|
||||
cls.comment_4 = Comment.objects.create(id=4, user=cls.user_3, text="foobarbaz")
|
||||
cls.comment_5 = Comment.objects.create(id=5, user=cls.user_3, text="barbaz")
|
||||
cls.comment_6 = Comment.objects.create(id=6, user=cls.user_3, text="baz")
|
||||
|
||||
def test_users_annotated_with_comments_id_count(self):
|
||||
user_1, user_2, user_3 = User.objects.annotate(Count("comments__id")).order_by(
|
||||
"pk"
|
||||
)
|
||||
|
||||
self.assertEqual(user_1, self.user_1)
|
||||
self.assertEqual(user_1.comments__id__count, 2)
|
||||
self.assertEqual(user_2, self.user_2)
|
||||
self.assertEqual(user_2.comments__id__count, 1)
|
||||
self.assertEqual(user_3, self.user_3)
|
||||
self.assertEqual(user_3.comments__id__count, 3)
|
||||
|
||||
def test_users_annotated_with_aliased_comments_id_count(self):
|
||||
user_1, user_2, user_3 = User.objects.annotate(
|
||||
comments_count=Count("comments__id")
|
||||
).order_by("pk")
|
||||
|
||||
self.assertEqual(user_1, self.user_1)
|
||||
self.assertEqual(user_1.comments_count, 2)
|
||||
self.assertEqual(user_2, self.user_2)
|
||||
self.assertEqual(user_2.comments_count, 1)
|
||||
self.assertEqual(user_3, self.user_3)
|
||||
self.assertEqual(user_3.comments_count, 3)
|
||||
|
||||
def test_users_annotated_with_comments_count(self):
|
||||
user_1, user_2, user_3 = User.objects.annotate(Count("comments")).order_by("pk")
|
||||
|
||||
self.assertEqual(user_1, self.user_1)
|
||||
self.assertEqual(user_1.comments__count, 2)
|
||||
self.assertEqual(user_2, self.user_2)
|
||||
self.assertEqual(user_2.comments__count, 1)
|
||||
self.assertEqual(user_3, self.user_3)
|
||||
self.assertEqual(user_3.comments__count, 3)
|
||||
|
||||
def test_users_annotated_with_comments_count_filter(self):
|
||||
user_1, user_2, user_3 = User.objects.annotate(
|
||||
comments__count=Count(
|
||||
"comments", filter=Q(pk__in=[self.user_1.pk, self.user_2.pk])
|
||||
)
|
||||
).order_by("pk")
|
||||
|
||||
self.assertEqual(user_1, self.user_1)
|
||||
self.assertEqual(user_1.comments__count, 2)
|
||||
self.assertEqual(user_2, self.user_2)
|
||||
self.assertEqual(user_2.comments__count, 1)
|
||||
self.assertEqual(user_3, self.user_3)
|
||||
self.assertEqual(user_3.comments__count, 0)
|
||||
|
||||
def test_count_distinct_not_supported(self):
|
||||
with self.assertRaisesMessage(
|
||||
NotSupportedError, "COUNT(DISTINCT) doesn't support composite primary keys"
|
||||
):
|
||||
self.assertIsNone(
|
||||
User.objects.annotate(comments__count=Count("comments", distinct=True))
|
||||
)
|
||||
|
||||
def test_user_values_annotated_with_comments_id_count(self):
|
||||
self.assertSequenceEqual(
|
||||
User.objects.values("pk").annotate(Count("comments__id")).order_by("pk"),
|
||||
(
|
||||
{"pk": self.user_1.pk, "comments__id__count": 2},
|
||||
{"pk": self.user_2.pk, "comments__id__count": 1},
|
||||
{"pk": self.user_3.pk, "comments__id__count": 3},
|
||||
),
|
||||
)
|
||||
|
||||
def test_user_values_annotated_with_filtered_comments_id_count(self):
|
||||
self.assertSequenceEqual(
|
||||
User.objects.values("pk")
|
||||
.annotate(
|
||||
comments_count=Count(
|
||||
"comments__id",
|
||||
filter=Q(comments__text__icontains="foo"),
|
||||
)
|
||||
)
|
||||
.order_by("pk"),
|
||||
(
|
||||
{"pk": self.user_1.pk, "comments_count": 1},
|
||||
{"pk": self.user_2.pk, "comments_count": 1},
|
||||
{"pk": self.user_3.pk, "comments_count": 1},
|
||||
),
|
||||
)
|
||||
|
||||
def test_filter_and_count_users_by_comments_fields(self):
|
||||
users = User.objects.filter(comments__id__gt=2).order_by("pk")
|
||||
self.assertEqual(users.count(), 4)
|
||||
self.assertSequenceEqual(
|
||||
users, (self.user_1, self.user_3, self.user_3, self.user_3)
|
||||
)
|
||||
|
||||
users = User.objects.filter(comments__text__icontains="foo").order_by("pk")
|
||||
self.assertEqual(users.count(), 3)
|
||||
self.assertSequenceEqual(users, (self.user_1, self.user_2, self.user_3))
|
||||
|
||||
users = User.objects.filter(comments__text__icontains="baz").order_by("pk")
|
||||
self.assertEqual(users.count(), 3)
|
||||
self.assertSequenceEqual(users, (self.user_3, self.user_3, self.user_3))
|
||||
|
||||
def test_order_by_comments_id_count(self):
|
||||
self.assertSequenceEqual(
|
||||
User.objects.annotate(comments_count=Count("comments__id")).order_by(
|
||||
"-comments_count"
|
||||
),
|
||||
(self.user_3, self.user_1, self.user_2),
|
||||
)
|
||||
Reference in New Issue
Block a user