mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
Fixed #25307 -- Fixed QuerySet.annotate() crash with conditional expressions.
Thanks Travis Newport for the tests and Josh Smeaton for contributing to the patch.
This commit is contained in:
@@ -9,7 +9,8 @@ from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import FieldError
|
||||
from django.db import connection
|
||||
from django.db.models import (
|
||||
Avg, Count, F, Max, Q, StdDev, Sum, Value, Variance,
|
||||
Avg, Case, Count, DecimalField, F, IntegerField, Max, Q, StdDev, Sum,
|
||||
Value, Variance, When,
|
||||
)
|
||||
from django.test import TestCase, skipUnlessAnyDBFeature, skipUnlessDBFeature
|
||||
from django.test.utils import Approximate
|
||||
@@ -371,6 +372,51 @@ class AggregationTests(TestCase):
|
||||
{'c__max': 3}
|
||||
)
|
||||
|
||||
def test_conditional_aggreate(self):
|
||||
# Conditional aggregation of a grouped queryset.
|
||||
self.assertEqual(
|
||||
Book.objects.annotate(c=Count('authors')).values('pk').aggregate(test=Sum(
|
||||
Case(When(c__gt=1, then=1), output_field=IntegerField())
|
||||
))['test'],
|
||||
3
|
||||
)
|
||||
|
||||
def test_sliced_conditional_aggregate(self):
|
||||
self.assertEqual(
|
||||
Author.objects.all()[:5].aggregate(test=Sum(Case(
|
||||
When(age__lte=35, then=1), output_field=IntegerField()
|
||||
)))['test'],
|
||||
3
|
||||
)
|
||||
|
||||
def test_annotated_conditional_aggregate(self):
|
||||
annotated_qs = Book.objects.annotate(discount_price=F('price') * 0.75)
|
||||
self.assertAlmostEqual(
|
||||
annotated_qs.aggregate(test=Avg(Case(
|
||||
When(pages__lt=400, then='discount_price'),
|
||||
output_field=DecimalField()
|
||||
)))['test'],
|
||||
22.27, places=2
|
||||
)
|
||||
|
||||
def test_distinct_conditional_aggregate(self):
|
||||
self.assertEqual(
|
||||
Book.objects.distinct().aggregate(test=Avg(Case(
|
||||
When(price=Decimal('29.69'), then='pages'),
|
||||
output_field=IntegerField()
|
||||
)))['test'],
|
||||
325
|
||||
)
|
||||
|
||||
def test_conditional_aggregate_on_complex_condition(self):
|
||||
self.assertEqual(
|
||||
Book.objects.distinct().aggregate(test=Avg(Case(
|
||||
When(Q(price__gte=Decimal('29')) & Q(price__lt=Decimal('30')), then='pages'),
|
||||
output_field=IntegerField()
|
||||
)))['test'],
|
||||
325
|
||||
)
|
||||
|
||||
def test_decimal_aggregate_annotation_filter(self):
|
||||
"""
|
||||
Filtering on an aggregate annotation with Decimal values should work.
|
||||
|
||||
Reference in New Issue
Block a user