Loading django/db/models/aggregates.py +2 −2 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ Classes to represent the definitions of aggregate functions. """ from django.core.exceptions import FieldError from django.db.models.expressions import Func, Value from django.db.models.expressions import Func, Star from django.db.models.fields import FloatField, IntegerField __all__ = [ Loading Loading @@ -98,7 +98,7 @@ class Count(Aggregate): def __init__(self, expression, distinct=False, **extra): if expression == '*': expression = Value(expression) expression = Star() super(Count, self).__init__( expression, distinct='DISTINCT ' if distinct else '', output_field=IntegerField(), **extra) Loading django/db/models/expressions.py +8 −0 Original line number Diff line number Diff line Loading @@ -593,6 +593,14 @@ class RawSQL(Expression): return [self] class Star(Expression): def __repr__(self): return "'*'" def as_sql(self, compiler, connection): return '*', [] class Random(Expression): def __init__(self): super(Random, self).__init__(output_field=fields.FloatField()) Loading docs/releases/1.8.5.txt +4 −0 Original line number Diff line number Diff line Loading @@ -32,3 +32,7 @@ Bugfixes * Fixed migrations crash on MySQL when adding a text or a blob field with an unhashable default (:ticket:`25393`). * Changed ``Count`` queries to execute ``COUNT(*)`` instead of ``COUNT('*')`` as versions of Django before 1.8 did (:ticket:`25377`). This may fix a performance regression on some databases. tests/aggregation/tests.py +6 −0 Original line number Diff line number Diff line Loading @@ -405,6 +405,12 @@ class AggregateTestCase(TestCase): vals = Book.objects.aggregate(Count("rating", distinct=True)) self.assertEqual(vals, {"rating__count": 4}) def test_count_star(self): with self.assertNumQueries(1) as ctx: Book.objects.aggregate(n=Count("*")) sql = ctx.captured_queries[0]['sql'] self.assertIn('SELECT COUNT(*) ', sql) def test_non_grouped_annotation_not_in_group_by(self): """ An annotation not included in values() before an aggregate should be Loading tests/expressions/tests.py +1 −0 Original line number Diff line number Diff line Loading @@ -878,6 +878,7 @@ class ReprTests(TestCase): def test_aggregates(self): self.assertEqual(repr(Avg('a')), "Avg(F(a))") self.assertEqual(repr(Count('a')), "Count(F(a), distinct=False)") self.assertEqual(repr(Count('*')), "Count('*', distinct=False)") self.assertEqual(repr(Max('a')), "Max(F(a))") self.assertEqual(repr(Min('a')), "Min(F(a))") self.assertEqual(repr(StdDev('a')), "StdDev(F(a), sample=False)") Loading Loading
django/db/models/aggregates.py +2 −2 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ Classes to represent the definitions of aggregate functions. """ from django.core.exceptions import FieldError from django.db.models.expressions import Func, Value from django.db.models.expressions import Func, Star from django.db.models.fields import FloatField, IntegerField __all__ = [ Loading Loading @@ -98,7 +98,7 @@ class Count(Aggregate): def __init__(self, expression, distinct=False, **extra): if expression == '*': expression = Value(expression) expression = Star() super(Count, self).__init__( expression, distinct='DISTINCT ' if distinct else '', output_field=IntegerField(), **extra) Loading
django/db/models/expressions.py +8 −0 Original line number Diff line number Diff line Loading @@ -593,6 +593,14 @@ class RawSQL(Expression): return [self] class Star(Expression): def __repr__(self): return "'*'" def as_sql(self, compiler, connection): return '*', [] class Random(Expression): def __init__(self): super(Random, self).__init__(output_field=fields.FloatField()) Loading
docs/releases/1.8.5.txt +4 −0 Original line number Diff line number Diff line Loading @@ -32,3 +32,7 @@ Bugfixes * Fixed migrations crash on MySQL when adding a text or a blob field with an unhashable default (:ticket:`25393`). * Changed ``Count`` queries to execute ``COUNT(*)`` instead of ``COUNT('*')`` as versions of Django before 1.8 did (:ticket:`25377`). This may fix a performance regression on some databases.
tests/aggregation/tests.py +6 −0 Original line number Diff line number Diff line Loading @@ -405,6 +405,12 @@ class AggregateTestCase(TestCase): vals = Book.objects.aggregate(Count("rating", distinct=True)) self.assertEqual(vals, {"rating__count": 4}) def test_count_star(self): with self.assertNumQueries(1) as ctx: Book.objects.aggregate(n=Count("*")) sql = ctx.captured_queries[0]['sql'] self.assertIn('SELECT COUNT(*) ', sql) def test_non_grouped_annotation_not_in_group_by(self): """ An annotation not included in values() before an aggregate should be Loading
tests/expressions/tests.py +1 −0 Original line number Diff line number Diff line Loading @@ -878,6 +878,7 @@ class ReprTests(TestCase): def test_aggregates(self): self.assertEqual(repr(Avg('a')), "Avg(F(a))") self.assertEqual(repr(Count('a')), "Count(F(a), distinct=False)") self.assertEqual(repr(Count('*')), "Count('*', distinct=False)") self.assertEqual(repr(Max('a')), "Max(F(a))") self.assertEqual(repr(Min('a')), "Min(F(a))") self.assertEqual(repr(StdDev('a')), "StdDev(F(a), sample=False)") Loading