[2.0.x] Fixed #28722 -- Made QuerySet.reverse() affect nulls_first/nulls_last.

Backport of 21a3a29dc9 from master
This commit is contained in:
Tomer Chachamu 2017-10-18 14:09:45 +01:00 committed by Tim Graham
parent f9a01d40d5
commit 57d46606ed
4 changed files with 27 additions and 16 deletions

View File

@ -790,6 +790,7 @@ answer newbie questions, and generally made Django that much better:
Tomáš Kopeček <permonik@m6.cz>
Tome Cvitan <tome@cvitan.com>
Tomek Paczkowski <tomek@hauru.eu>
Tomer Chachamu
Tommy Beadle <tbeadle@gmail.com>
Tore Lundqvist <tore.lundqvist@gmail.com>
torne-django@wolfpuppy.org.uk

View File

@ -1144,6 +1144,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):

View File

@ -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`).

View File

@ -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],
)