|
1 from datetime import datetime |
|
2 from operator import attrgetter |
|
3 |
|
4 from django.test import TestCase |
|
5 |
|
6 from models import Article |
|
7 |
|
8 |
|
9 class OrderingTests(TestCase): |
|
10 def test_basic(self): |
|
11 a1 = Article.objects.create( |
|
12 headline="Article 1", pub_date=datetime(2005, 7, 26) |
|
13 ) |
|
14 a2 = Article.objects.create( |
|
15 headline="Article 2", pub_date=datetime(2005, 7, 27) |
|
16 ) |
|
17 a3 = Article.objects.create( |
|
18 headline="Article 3", pub_date=datetime(2005, 7, 27) |
|
19 ) |
|
20 a4 = Article.objects.create( |
|
21 headline="Article 4", pub_date=datetime(2005, 7, 28) |
|
22 ) |
|
23 |
|
24 # By default, Article.objects.all() orders by pub_date descending, then |
|
25 # headline ascending. |
|
26 self.assertQuerysetEqual( |
|
27 Article.objects.all(), [ |
|
28 "Article 4", |
|
29 "Article 2", |
|
30 "Article 3", |
|
31 "Article 1", |
|
32 ], |
|
33 attrgetter("headline") |
|
34 ) |
|
35 |
|
36 # Override ordering with order_by, which is in the same format as the |
|
37 # ordering attribute in models. |
|
38 self.assertQuerysetEqual( |
|
39 Article.objects.order_by("headline"), [ |
|
40 "Article 1", |
|
41 "Article 2", |
|
42 "Article 3", |
|
43 "Article 4", |
|
44 ], |
|
45 attrgetter("headline") |
|
46 ) |
|
47 self.assertQuerysetEqual( |
|
48 Article.objects.order_by("pub_date", "-headline"), [ |
|
49 "Article 1", |
|
50 "Article 3", |
|
51 "Article 2", |
|
52 "Article 4", |
|
53 ], |
|
54 attrgetter("headline") |
|
55 ) |
|
56 |
|
57 # Only the last order_by has any effect (since they each override any |
|
58 # previous ordering). |
|
59 self.assertQuerysetEqual( |
|
60 Article.objects.order_by("id"), [ |
|
61 "Article 1", |
|
62 "Article 2", |
|
63 "Article 3", |
|
64 "Article 4", |
|
65 ], |
|
66 attrgetter("headline") |
|
67 ) |
|
68 self.assertQuerysetEqual( |
|
69 Article.objects.order_by("id").order_by("-headline"), [ |
|
70 "Article 4", |
|
71 "Article 3", |
|
72 "Article 2", |
|
73 "Article 1", |
|
74 ], |
|
75 attrgetter("headline") |
|
76 ) |
|
77 |
|
78 # Use the 'stop' part of slicing notation to limit the results. |
|
79 self.assertQuerysetEqual( |
|
80 Article.objects.order_by("headline")[:2], [ |
|
81 "Article 1", |
|
82 "Article 2", |
|
83 ], |
|
84 attrgetter("headline") |
|
85 ) |
|
86 |
|
87 # Use the 'stop' and 'start' parts of slicing notation to offset the |
|
88 # result list. |
|
89 self.assertQuerysetEqual( |
|
90 Article.objects.order_by("headline")[1:3], [ |
|
91 "Article 2", |
|
92 "Article 3", |
|
93 ], |
|
94 attrgetter("headline") |
|
95 ) |
|
96 |
|
97 # Getting a single item should work too: |
|
98 self.assertEqual(Article.objects.all()[0], a4) |
|
99 |
|
100 # Use '?' to order randomly. |
|
101 self.assertEqual( |
|
102 len(list(Article.objects.order_by("?"))), 4 |
|
103 ) |
|
104 |
|
105 # Ordering can be reversed using the reverse() method on a queryset. |
|
106 # This allows you to extract things like "the last two items" (reverse |
|
107 # and then take the first two). |
|
108 self.assertQuerysetEqual( |
|
109 Article.objects.all().reverse()[:2], [ |
|
110 "Article 1", |
|
111 "Article 3", |
|
112 ], |
|
113 attrgetter("headline") |
|
114 ) |
|
115 |
|
116 # Ordering can be based on fields included from an 'extra' clause |
|
117 self.assertQuerysetEqual( |
|
118 Article.objects.extra(select={"foo": "pub_date"}, order_by=["foo", "headline"]), [ |
|
119 "Article 1", |
|
120 "Article 2", |
|
121 "Article 3", |
|
122 "Article 4", |
|
123 ], |
|
124 attrgetter("headline") |
|
125 ) |
|
126 |
|
127 # If the extra clause uses an SQL keyword for a name, it will be |
|
128 # protected by quoting. |
|
129 self.assertQuerysetEqual( |
|
130 Article.objects.extra(select={"order": "pub_date"}, order_by=["order", "headline"]), [ |
|
131 "Article 1", |
|
132 "Article 2", |
|
133 "Article 3", |
|
134 "Article 4", |
|
135 ], |
|
136 attrgetter("headline") |
|
137 ) |