0
0
mirror of https://github.com/django/django.git synced 2024-11-28 21:43:13 +01:00

Fixed #32007 -- Fixed queryset crash with Q() annotation and aggregation.

Thanks Gordon Wrigley for the report.

Regression in 8a6df55f2d.
This commit is contained in:
Mariusz Felisiak 2020-09-15 11:40:59 +02:00 committed by GitHub
parent 7be6a6a4d6
commit eaf9764d3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 0 deletions

View File

@ -159,6 +159,9 @@ class WhereNode(tree.Node):
clone.relabel_aliases(change_map) clone.relabel_aliases(change_map)
return clone return clone
def copy(self):
return self.clone()
@classmethod @classmethod
def _contains_aggregate(cls, obj): def _contains_aggregate(cls, obj):
if isinstance(obj, tree.Node): if isinstance(obj, tree.Node):

View File

@ -16,3 +16,6 @@ Bugfixes
attribute returned incorrectly ``True`` for ``GROUP BY`` queries (e.g. attribute returned incorrectly ``True`` for ``GROUP BY`` queries (e.g.
``.annotate().values()``) on models with ``Meta.ordering``. A model's ``.annotate().values()``) on models with ``Meta.ordering``. A model's
``Meta.ordering`` doesn't affect such queries (:ticket:`31990`). ``Meta.ordering`` doesn't affect such queries (:ticket:`31990`).
* Fixed a regression in Django 3.1 where a queryset would crash if it contained
an aggregation and a ``Q`` object annotation (:ticket:`32007`).

View File

@ -183,6 +183,17 @@ class NonAggregateAnnotationTestCase(TestCase):
self.assertEqual(book.combined, 13410.0) self.assertEqual(book.combined, 13410.0)
self.assertEqual(book.rating_count, 1) self.assertEqual(book.rating_count, 1)
def test_q_expression_annotation_with_aggregation(self):
book = Book.objects.filter(isbn='159059725').annotate(
isnull_pubdate=ExpressionWrapper(
Q(pubdate__isnull=True),
output_field=BooleanField(),
),
rating_count=Count('rating'),
).first()
self.assertEqual(book.isnull_pubdate, False)
self.assertEqual(book.rating_count, 1)
def test_aggregate_over_annotation(self): def test_aggregate_over_annotation(self):
agg = Author.objects.annotate(other_age=F('age')).aggregate(otherage_sum=Sum('other_age')) agg = Author.objects.annotate(other_age=F('age')).aggregate(otherage_sum=Sum('other_age'))
other_agg = Author.objects.aggregate(age_sum=Sum('age')) other_agg = Author.objects.aggregate(age_sum=Sum('age'))