Fixed #30501 -- Preventing QuerySet.reverse() from mutating expressions in QuerySet.order_by and Meta.ordering.

This commit is contained in:
Mariusz Felisiak 2019-05-23 20:33:37 +02:00 committed by GitHub
parent 2007e11d70
commit f8b8b00f01
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 7 deletions

View File

@ -281,6 +281,7 @@ class SQLCompiler:
if not isinstance(field, OrderBy): if not isinstance(field, OrderBy):
field = field.asc() field = field.asc()
if not self.query.standard_ordering: if not self.query.standard_ordering:
field = field.copy()
field.reverse_ordering() field.reverse_ordering()
order_by.append((field, False)) order_by.append((field, False))
continue continue

View File

@ -210,6 +210,15 @@ class OrderingTests(TestCase):
def test_reverse_ordering_pure(self): def test_reverse_ordering_pure(self):
qs1 = Article.objects.order_by(F('headline').asc()) qs1 = Article.objects.order_by(F('headline').asc())
qs2 = qs1.reverse() qs2 = qs1.reverse()
self.assertQuerysetEqual(
qs2, [
'Article 4',
'Article 3',
'Article 2',
'Article 1',
],
attrgetter('headline'),
)
self.assertQuerysetEqual( self.assertQuerysetEqual(
qs1, [ qs1, [
"Article 1", "Article 1",
@ -219,14 +228,29 @@ class OrderingTests(TestCase):
], ],
attrgetter("headline") attrgetter("headline")
) )
def test_reverse_meta_ordering_pure(self):
Article.objects.create(
headline='Article 5',
pub_date=datetime(2005, 7, 30),
author=self.author_1,
second_author=self.author_2,
)
Article.objects.create(
headline='Article 5',
pub_date=datetime(2005, 7, 30),
author=self.author_2,
second_author=self.author_1,
)
self.assertQuerysetEqual( self.assertQuerysetEqual(
qs2, [ Article.objects.filter(headline='Article 5').reverse(),
"Article 4", ['Name 2', 'Name 1'],
"Article 3", attrgetter('author.name'),
"Article 2", )
"Article 1", self.assertQuerysetEqual(
], Article.objects.filter(headline='Article 5'),
attrgetter("headline") ['Name 1', 'Name 2'],
attrgetter('author.name'),
) )
def test_no_reordering_after_slicing(self): def test_no_reordering_after_slicing(self):