From 21a3a29dc9d138c248fd7922923b3ec710735c6c Mon Sep 17 00:00:00 2001 From: Tomer Chachamu Date: Wed, 18 Oct 2017 14:09:45 +0100 Subject: [PATCH] Fixed #28722 -- Made QuerySet.reverse() affect nulls_first/nulls_last. --- AUTHORS | 1 + django/db/models/expressions.py | 3 +++ docs/releases/1.11.7.txt | 3 +++ tests/ordering/tests.py | 36 ++++++++++++++++++--------------- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/AUTHORS b/AUTHORS index ca89ff4a76..34395516ae 100644 --- a/AUTHORS +++ b/AUTHORS @@ -792,6 +792,7 @@ answer newbie questions, and generally made Django that much better: Tomáš Kopeček Tome Cvitan Tomek Paczkowski + Tomer Chachamu Tommy Beadle Tore Lundqvist torne-django@wolfpuppy.org.uk diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index e11c32c9e7..52c6afdb78 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -1132,6 +1132,9 @@ class OrderBy(BaseExpression): def reverse_ordering(self): self.descending = not self.descending + if self.nulls_first or self.nulls_last: + self.nulls_first = not self.nulls_first + self.nulls_last = not self.nulls_last return self def asc(self): diff --git a/docs/releases/1.11.7.txt b/docs/releases/1.11.7.txt index 717174c625..fe2cf2e300 100644 --- a/docs/releases/1.11.7.txt +++ b/docs/releases/1.11.7.txt @@ -13,3 +13,6 @@ Bugfixes argument is a callable that returns ``None`` (:ticket:`28601`). * Fixed the Basque ``DATE_FORMAT`` string (:ticket:`28710`). + +* Made ``QuerySet.reverse()`` affect ``nulls_first`` and ``nulls_last`` + (:ticket:`28722`). diff --git a/tests/ordering/tests.py b/tests/ordering/tests.py index dbc924b06b..07c319b4c3 100644 --- a/tests/ordering/tests.py +++ b/tests/ordering/tests.py @@ -92,24 +92,28 @@ class OrderingTests(TestCase): with self.assertRaisesMessage(ValueError, msg): Article.objects.order_by(F("author").desc(nulls_last=True, nulls_first=True)) + def assertQuerysetEqualReversible(self, queryset, sequence): + self.assertSequenceEqual(queryset, sequence) + self.assertSequenceEqual(queryset.reverse(), list(reversed(sequence))) + def test_order_by_nulls_last(self): Article.objects.filter(headline="Article 3").update(author=self.author_1) Article.objects.filter(headline="Article 4").update(author=self.author_2) # asc and desc are chainable with nulls_last. - self.assertSequenceEqual( - Article.objects.order_by(F("author").desc(nulls_last=True)), + self.assertQuerysetEqualReversible( + Article.objects.order_by(F("author").desc(nulls_last=True), 'headline'), [self.a4, self.a3, self.a1, self.a2], ) - self.assertSequenceEqual( - Article.objects.order_by(F("author").asc(nulls_last=True)), + self.assertQuerysetEqualReversible( + Article.objects.order_by(F("author").asc(nulls_last=True), 'headline'), [self.a3, self.a4, self.a1, self.a2], ) - self.assertSequenceEqual( - Article.objects.order_by(Upper("author__name").desc(nulls_last=True)), + self.assertQuerysetEqualReversible( + Article.objects.order_by(Upper("author__name").desc(nulls_last=True), 'headline'), [self.a4, self.a3, self.a1, self.a2], ) - self.assertSequenceEqual( - Article.objects.order_by(Upper("author__name").asc(nulls_last=True)), + self.assertQuerysetEqualReversible( + Article.objects.order_by(Upper("author__name").asc(nulls_last=True), 'headline'), [self.a3, self.a4, self.a1, self.a2], ) @@ -117,20 +121,20 @@ class OrderingTests(TestCase): Article.objects.filter(headline="Article 3").update(author=self.author_1) Article.objects.filter(headline="Article 4").update(author=self.author_2) # asc and desc are chainable with nulls_first. - self.assertSequenceEqual( - Article.objects.order_by(F("author").asc(nulls_first=True)), + self.assertQuerysetEqualReversible( + Article.objects.order_by(F("author").asc(nulls_first=True), 'headline'), [self.a1, self.a2, self.a3, self.a4], ) - self.assertSequenceEqual( - Article.objects.order_by(F("author").desc(nulls_first=True)), + self.assertQuerysetEqualReversible( + Article.objects.order_by(F("author").desc(nulls_first=True), 'headline'), [self.a1, self.a2, self.a4, self.a3], ) - self.assertSequenceEqual( - Article.objects.order_by(Upper("author__name").asc(nulls_first=True)), + self.assertQuerysetEqualReversible( + Article.objects.order_by(Upper("author__name").asc(nulls_first=True), 'headline'), [self.a1, self.a2, self.a3, self.a4], ) - self.assertSequenceEqual( - Article.objects.order_by(Upper("author__name").desc(nulls_first=True)), + self.assertQuerysetEqualReversible( + Article.objects.order_by(Upper("author__name").desc(nulls_first=True), 'headline'), [self.a1, self.a2, self.a4, self.a3], )