Fixed #24923 -- errored out nicely when using aggregates in order_by()

This commit is contained in:
Anssi Kääriäinen 2015-06-04 17:50:14 +03:00 committed by Tim Graham
parent 83f6373030
commit 6f403056f0
2 changed files with 13 additions and 0 deletions

View File

@ -1643,6 +1643,11 @@ class Query(object):
for item in ordering: for item in ordering:
if not hasattr(item, 'resolve_expression') and not ORDER_PATTERN.match(item): if not hasattr(item, 'resolve_expression') and not ORDER_PATTERN.match(item):
errors.append(item) errors.append(item)
if getattr(item, 'contains_aggregate', False):
raise FieldError(
'Using an aggregate in order_by() without also including '
'it in annotate() is not allowed: %s' % item
)
if errors: if errors:
raise FieldError('Invalid order_by arguments: %s' % errors) raise FieldError('Invalid order_by arguments: %s' % errors)
if ordering: if ordering:

View File

@ -105,6 +105,14 @@ class AggregateTestCase(TestCase):
def test_empty_aggregate(self): def test_empty_aggregate(self):
self.assertEqual(Author.objects.all().aggregate(), {}) self.assertEqual(Author.objects.all().aggregate(), {})
def test_aggregate_in_order_by(self):
msg = (
'Using an aggregate in order_by() without also including it in '
'annotate() is not allowed: Avg(F(book__rating)'
)
with self.assertRaisesMessage(FieldError, msg):
Author.objects.values('age').order_by(Avg('book__rating'))
def test_single_aggregate(self): def test_single_aggregate(self):
vals = Author.objects.aggregate(Avg("age")) vals = Author.objects.aggregate(Avg("age"))
self.assertEqual(vals, {"age__avg": Approximate(37.4, places=1)}) self.assertEqual(vals, {"age__avg": Approximate(37.4, places=1)})