diff options
author | Josh Smeaton <josh.smeaton@gmail.com> | 2017-01-17 02:03:15 +1100 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2017-01-16 10:03:15 -0500 |
commit | 1df89a60c5b7a28d7fda4c9ba7c07f02fd7de0fa (patch) | |
tree | 682ee02fb33cc654803d37b46b65dc38f32d506e /tests/aggregation_regress | |
parent | f2d2f178965584a1ebe666a6621ef82581233fab (diff) | |
download | django-1df89a60c5b7a28d7fda4c9ba7c07f02fd7de0fa.tar.gz |
Fixed #25307 -- Fixed QuerySet.annotate() crash with conditional expressions.
Thanks Travis Newport for the tests and Josh Smeaton for contributing
to the patch.
Diffstat (limited to 'tests/aggregation_regress')
-rw-r--r-- | tests/aggregation_regress/tests.py | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/tests/aggregation_regress/tests.py b/tests/aggregation_regress/tests.py index 0229020234..2958736fe9 100644 --- a/tests/aggregation_regress/tests.py +++ b/tests/aggregation_regress/tests.py @@ -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. |