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
|
from __future__ import unicode_literals
from operator import attrgetter
from django.apps.registry import Apps
from django.db import models
from django.test import TestCase
from .models import Answer, Dimension, Entity, Post, Question
class OrderWithRespectToTests(TestCase):
# Hook to allow subclasses to run these tests with alternate models.
Answer = Answer
Question = Question
@classmethod
def setUpTestData(cls):
cls.q1 = cls.Question.objects.create(text="Which Beatle starts with the letter 'R'?")
cls.Answer.objects.create(text="John", question=cls.q1)
cls.Answer.objects.create(text="Paul", question=cls.q1)
cls.Answer.objects.create(text="George", question=cls.q1)
cls.Answer.objects.create(text="Ringo", question=cls.q1)
def test_default_to_insertion_order(self):
# Answers will always be ordered in the order they were inserted.
self.assertQuerysetEqual(
self.q1.answer_set.all(), [
"John", "Paul", "George", "Ringo",
],
attrgetter("text"),
)
def test_previous_and_next_in_order(self):
# We can retrieve the answers related to a particular object, in the
# order they were created, once we have a particular object.
a1 = self.q1.answer_set.all()[0]
self.assertEqual(a1.text, "John")
self.assertEqual(a1.get_next_in_order().text, "Paul")
a2 = list(self.q1.answer_set.all())[-1]
self.assertEqual(a2.text, "Ringo")
self.assertEqual(a2.get_previous_in_order().text, "George")
def test_item_ordering(self):
# We can retrieve the ordering of the queryset from a particular item.
a1 = self.q1.answer_set.all()[1]
id_list = [o.pk for o in self.q1.answer_set.all()]
self.assertSequenceEqual(a1.question.get_answer_order(), id_list)
# It doesn't matter which answer we use to check the order, it will
# always be the same.
a2 = self.Answer.objects.create(text="Number five", question=self.q1)
self.assertListEqual(
list(a1.question.get_answer_order()), list(a2.question.get_answer_order())
)
def test_change_ordering(self):
# The ordering can be altered
a = self.Answer.objects.create(text="Number five", question=self.q1)
# Swap the last two items in the order list
id_list = [o.pk for o in self.q1.answer_set.all()]
x = id_list.pop()
id_list.insert(-1, x)
# By default, the ordering is different from the swapped version
self.assertNotEqual(list(a.question.get_answer_order()), id_list)
# Change the ordering to the swapped version -
# this changes the ordering of the queryset.
a.question.set_answer_order(id_list)
self.assertQuerysetEqual(
self.q1.answer_set.all(), [
"John", "Paul", "George", "Number five", "Ringo"
],
attrgetter("text")
)
class OrderWithRespectToTests2(TestCase):
# Provide the Post model as a class attribute so that we can subclass this
# test case in contenttypes_tests.test_order_with_respect_to and run these
# tests with alternative implementations of Post.
Post = Post
def test_recursive_ordering(self):
p1 = self.Post.objects.create(title="1")
p2 = self.Post.objects.create(title="2")
p1_1 = self.Post.objects.create(title="1.1", parent=p1)
p1_2 = self.Post.objects.create(title="1.2", parent=p1)
self.Post.objects.create(title="2.1", parent=p2)
p1_3 = self.Post.objects.create(title="1.3", parent=p1)
self.assertSequenceEqual(p1.get_post_order(), [p1_1.pk, p1_2.pk, p1_3.pk])
def test_duplicate_order_field(self):
test_apps = Apps(['order_with_respect_to'])
class Bar(models.Model):
class Meta:
apps = test_apps
app_label = 'order_with_respect_to'
class Foo(models.Model):
bar = models.ForeignKey(Bar, models.CASCADE)
order = models.OrderWrt()
class Meta:
order_with_respect_to = 'bar'
apps = test_apps
app_label = 'order_with_respect_to'
count = 0
for field in Foo._meta.local_fields:
if isinstance(field, models.OrderWrt):
count += 1
self.assertEqual(count, 1)
class TestOrderWithRespectToOneToOnePK(TestCase):
def test_set_order(self):
e = Entity.objects.create()
d = Dimension.objects.create(entity=e)
c1 = d.component_set.create()
c2 = d.component_set.create()
d.set_component_order([c1.id, c2.id])
self.assertQuerysetEqual(d.component_set.all(), [c1.id, c2.id], attrgetter('pk'))
|