summaryrefslogtreecommitdiff
path: root/tests/modeltests/ordering/tests.py
blob: b1b5253682e46b935d0c2f95d71b16d0a26b8e3b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
from __future__ import absolute_import

from datetime import datetime
from operator import attrgetter

from django.test import TestCase

from .models import Article, ArticlePKOrdering


class OrderingTests(TestCase):
    def test_basic(self):
        a1 = Article.objects.create(
            headline="Article 1", pub_date=datetime(2005, 7, 26)
        )
        a2 = Article.objects.create(
            headline="Article 2", pub_date=datetime(2005, 7, 27)
        )
        a3 = Article.objects.create(
            headline="Article 3", pub_date=datetime(2005, 7, 27)
        )
        a4 = Article.objects.create(
            headline="Article 4", pub_date=datetime(2005, 7, 28)
        )

        # By default, Article.objects.all() orders by pub_date descending, then
        # headline ascending.
        self.assertQuerysetEqual(
            Article.objects.all(), [
                "Article 4",
                "Article 2",
                "Article 3",
                "Article 1",
            ],
            attrgetter("headline")
        )

        # Override ordering with order_by, which is in the same format as the
        # ordering attribute in models.
        self.assertQuerysetEqual(
            Article.objects.order_by("headline"), [
                "Article 1",
                "Article 2",
                "Article 3",
                "Article 4",
            ],
            attrgetter("headline")
        )
        self.assertQuerysetEqual(
            Article.objects.order_by("pub_date", "-headline"), [
                "Article 1",
                "Article 3",
                "Article 2",
                "Article 4",
            ],
            attrgetter("headline")
        )

        # Only the last order_by has any effect (since they each override any
        # previous ordering).
        self.assertQuerysetEqual(
            Article.objects.order_by("id"), [
                "Article 1",
                "Article 2",
                "Article 3",
                "Article 4",
            ],
            attrgetter("headline")
        )
        self.assertQuerysetEqual(
            Article.objects.order_by("id").order_by("-headline"), [
                "Article 4",
                "Article 3",
                "Article 2",
                "Article 1",
            ],
            attrgetter("headline")
        )

        # Use the 'stop' part of slicing notation to limit the results.
        self.assertQuerysetEqual(
            Article.objects.order_by("headline")[:2], [
                "Article 1",
                "Article 2",
            ],
            attrgetter("headline")
        )

        # Use the 'stop' and 'start' parts of slicing notation to offset the
        # result list.
        self.assertQuerysetEqual(
            Article.objects.order_by("headline")[1:3], [
                "Article 2",
                "Article 3",
            ],
            attrgetter("headline")
        )

        # Getting a single item should work too:
        self.assertEqual(Article.objects.all()[0], a4)

        # Use '?' to order randomly.
        self.assertEqual(
            len(list(Article.objects.order_by("?"))), 4
        )

        # Ordering can be reversed using the reverse() method on a queryset.
        # This allows you to extract things like "the last two items" (reverse
        # and then take the first two).
        self.assertQuerysetEqual(
            Article.objects.all().reverse()[:2], [
                "Article 1",
                "Article 3",
            ],
            attrgetter("headline")
        )

        # Ordering can be based on fields included from an 'extra' clause
        self.assertQuerysetEqual(
            Article.objects.extra(select={"foo": "pub_date"}, order_by=["foo", "headline"]), [
                "Article 1",
                "Article 2",
                "Article 3",
                "Article 4",
            ],
            attrgetter("headline")
        )

        # If the extra clause uses an SQL keyword for a name, it will be
        # protected by quoting.
        self.assertQuerysetEqual(
            Article.objects.extra(select={"order": "pub_date"}, order_by=["order", "headline"]), [
                "Article 1",
                "Article 2",
                "Article 3",
                "Article 4",
            ],
            attrgetter("headline")
        )

    def test_order_by_pk(self):
        """
        Ensure that 'pk' works as an ordering option in Meta.
        Refs #8291.
        """
        a1 = ArticlePKOrdering.objects.create(
            pk=1, headline="Article 1", pub_date=datetime(2005, 7, 26)
        )
        a2 = ArticlePKOrdering.objects.create(
            pk=2, headline="Article 2", pub_date=datetime(2005, 7, 27)
        )
        a3 = ArticlePKOrdering.objects.create(
            pk=3, headline="Article 3", pub_date=datetime(2005, 7, 27)
        )
        a4 = ArticlePKOrdering.objects.create(
            pk=4, headline="Article 4", pub_date=datetime(2005, 7, 28)
        )

        self.assertQuerysetEqual(
            ArticlePKOrdering.objects.all(), [
                "Article 4",
                "Article 3",
                "Article 2",
                "Article 1",
            ],
            attrgetter("headline")
        )