Преглед на файлове

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

Mariusz Felisiak преди 5 години
родител
ревизия
f8b8b00f01
променени са 2 файла, в които са добавени 32 реда и са изтрити 7 реда
  1. 1 0
      django/db/models/sql/compiler.py
  2. 31 7
      tests/ordering/tests.py

+ 1 - 0
django/db/models/sql/compiler.py

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

+ 31 - 7
tests/ordering/tests.py

@@ -210,6 +210,15 @@ class OrderingTests(TestCase):
     def test_reverse_ordering_pure(self):
         qs1 = Article.objects.order_by(F('headline').asc())
         qs2 = qs1.reverse()
+        self.assertQuerysetEqual(
+            qs2, [
+                'Article 4',
+                'Article 3',
+                'Article 2',
+                'Article 1',
+            ],
+            attrgetter('headline'),
+        )
         self.assertQuerysetEqual(
             qs1, [
                 "Article 1",
@@ -219,14 +228,29 @@ class OrderingTests(TestCase):
             ],
             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(
-            qs2, [
-                "Article 4",
-                "Article 3",
-                "Article 2",
-                "Article 1",
-            ],
-            attrgetter("headline")
+            Article.objects.filter(headline='Article 5').reverse(),
+            ['Name 2', 'Name 1'],
+            attrgetter('author.name'),
+        )
+        self.assertQuerysetEqual(
+            Article.objects.filter(headline='Article 5'),
+            ['Name 1', 'Name 2'],
+            attrgetter('author.name'),
         )
 
     def test_no_reordering_after_slicing(self):