Skip to content

Commit

Permalink
Raise an error when aggregation alias is conflicting with an annotation
Browse files Browse the repository at this point in the history
Co-authored-by: Nick Pope <nick.pope@flightdataservices.com>
  • Loading branch information
David-Wobrock and ngnpope committed Sep 17, 2020
1 parent f3901b5 commit edbd024
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 0 deletions.
3 changes: 3 additions & 0 deletions django/db/models/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ def aggregate(self, *args, **kwargs):

query = self.query.chain()
for (alias, aggregate_expr) in kwargs.items():
if alias in query.annotations:
raise ValueError("Aggregation alias '%s' conflicts with an existing annotation." % alias)

query.add_annotation(aggregate_expr, alias, is_summary=True)
if not query.annotations[alias].contains_aggregate:
raise TypeError("%s is not an aggregate expression" % alias)
Expand Down
5 changes: 5 additions & 0 deletions tests/aggregation/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,11 @@ def test_annotate_over_annotate(self):

self.assertEqual(author.sum_age, other_author.sum_age)

def test_same_annotation_aggregate_alias(self):
msg = "Aggregation alias 'age_alias' conflicts with an existing annotation."
with self.assertRaisesMessage(ValueError, msg):
Author.objects.annotate(age_alias=F('age')).aggregate(age_alias=Sum(F('age')))

def test_annotated_aggregate_over_annotated_aggregate(self):
with self.assertRaisesMessage(FieldError, "Cannot compute Sum('id__max'): 'id__max' is an aggregate"):
Book.objects.annotate(Max('id')).annotate(Sum('id__max'))
Expand Down

0 comments on commit edbd024

Please sign in to comment.