summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Smeaton <josh.smeaton@gmail.com>2015-03-05 17:10:48 +1100
committerJosh Smeaton <josh.smeaton@gmail.com>2015-03-06 13:31:43 +1100
commit823f8cdbc91f85a8ab3cb1ccfec5659037b5c148 (patch)
tree7b7429632d38e8d6a56f04df6bd37192137363e0
parentbd7c879d5a0daeaa58f2a32901db6e8d8ed5212d (diff)
[1.8.x] Fixed #24420 -- Allowed ordering by case expressions
Backport of ceaf31adfff3801f1092a215f73704e15a70e90c from master
-rw-r--r--django/db/models/expressions.py5
-rw-r--r--tests/annotations/tests.py18
-rw-r--r--tests/expressions_case/tests.py24
3 files changed, 47 insertions, 0 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 00a6424886..41ce6ba187 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -630,6 +630,11 @@ class Ref(ExpressionNode):
def set_source_expressions(self, exprs):
self.source, = exprs
+ def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
+ # The sub-expression `source` has already been resolved, as this is
+ # just a reference to the name of `source`.
+ return self
+
def relabeled_clone(self, relabels):
return self
diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py
index 2bf441716b..3f50463b48 100644
--- a/tests/annotations/tests.py
+++ b/tests/annotations/tests.py
@@ -197,6 +197,24 @@ class NonAggregateAnnotationTestCase(TestCase):
book = Book.objects.annotate(no_value=Value(None, output_field=IntegerField())).first()
self.assertIsNone(book.no_value)
+ def test_order_by_annotation(self):
+ authors = Author.objects.annotate(other_age=F('age')).order_by('other_age')
+ self.assertQuerysetEqual(
+ authors, [
+ 25, 29, 29, 34, 35, 37, 45, 46, 57,
+ ],
+ lambda a: a.other_age
+ )
+
+ def test_order_by_aggregate(self):
+ authors = Author.objects.values('age').annotate(age_count=Count('age')).order_by('age_count', 'age')
+ self.assertQuerysetEqual(
+ authors, [
+ (25, 1), (34, 1), (35, 1), (37, 1), (45, 1), (46, 1), (57, 1), (29, 2),
+ ],
+ lambda a: (a['age'], a['age_count'])
+ )
+
def test_column_field_ordering(self):
"""
Test that columns are aligned in the correct order for
diff --git a/tests/expressions_case/tests.py b/tests/expressions_case/tests.py
index b1b4c77948..1ebaf6d220 100644
--- a/tests/expressions_case/tests.py
+++ b/tests/expressions_case/tests.py
@@ -995,6 +995,30 @@ class CaseExpressionTests(TestCase):
transform=attrgetter('integer', 'integer2', 'test')
)
+ def test_order_by_conditional_implicit(self):
+ self.assertQuerysetEqual(
+ CaseTestModel.objects.filter(integer__lte=2).annotate(test=Case(
+ When(integer=1, then=2),
+ When(integer=2, then=1),
+ default=3,
+ output_field=models.IntegerField(),
+ )).order_by('test', 'pk'),
+ [(2, 1), (2, 1), (1, 2)],
+ transform=attrgetter('integer', 'test')
+ )
+
+ def test_order_by_conditional_explicit(self):
+ self.assertQuerysetEqual(
+ CaseTestModel.objects.filter(integer__lte=2).annotate(test=Case(
+ When(integer=1, then=2),
+ When(integer=2, then=1),
+ default=3,
+ output_field=models.IntegerField(),
+ )).order_by(F('test').asc(), 'pk'),
+ [(2, 1), (2, 1), (1, 2)],
+ transform=attrgetter('integer', 'test')
+ )
+
class CaseDocumentationExamples(TestCase):
@classmethod