~ubuntu-branches/ubuntu/quantal/python-django/quantal

« back to all changes in this revision

Viewing changes to tests/modeltests/delete/models.py

  • Committer: Bazaar Package Importer
  • Author(s): Scott James Remnant
  • Date: 2008-11-15 19:15:33 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20081115191533-xbt1ut2xf4fvwtvc
Tags: 1.0.1-0ubuntu1
* New upstream release:
  - Bug fixes.

* The tests/ sub-directory appaers to have been dropped upstream, so pull
  our patch to workaround the tests and modify the rules.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# coding: utf-8
2
 
"""
3
 
Tests for some corner cases with deleting.
4
 
"""
5
 
 
6
 
from django.db import models
7
 
 
8
 
class DefaultRepr(object):
9
 
    def __repr__(self):
10
 
        return u"<%s: %s>" % (self.__class__.__name__, self.__dict__)
11
 
 
12
 
class A(DefaultRepr, models.Model):
13
 
    pass
14
 
 
15
 
class B(DefaultRepr, models.Model):
16
 
    a = models.ForeignKey(A)
17
 
 
18
 
class C(DefaultRepr, models.Model):
19
 
    b = models.ForeignKey(B)
20
 
 
21
 
class D(DefaultRepr, models.Model):
22
 
    c = models.ForeignKey(C)
23
 
    a = models.ForeignKey(A)
24
 
 
25
 
# Simplified, we have:
26
 
# A
27
 
# B -> A
28
 
# C -> B
29
 
# D -> C
30
 
# D -> A
31
 
 
32
 
# So, we must delete Ds first of all, then Cs then Bs then As.
33
 
# However, if we start at As, we might find Bs first (in which 
34
 
# case things will be nice), or find Ds first.
35
 
 
36
 
# Some mutually dependent models, but nullable
37
 
class E(DefaultRepr, models.Model):
38
 
    f = models.ForeignKey('F', null=True, related_name='e_rel')
39
 
 
40
 
class F(DefaultRepr, models.Model):
41
 
    e = models.ForeignKey(E, related_name='f_rel')
42
 
 
43
 
 
44
 
__test__ = {'API_TESTS': """
45
 
### Tests for models A,B,C,D ###
46
 
 
47
 
## First, test the CollectedObjects data structure directly
48
 
 
49
 
>>> from django.db.models.query import CollectedObjects
50
 
 
51
 
>>> g = CollectedObjects()
52
 
>>> g.add("key1", 1, "item1", None)
53
 
False
54
 
>>> g["key1"]
55
 
{1: 'item1'}
56
 
>>> g.add("key2", 1, "item1", "key1")
57
 
False
58
 
>>> g.add("key2", 2, "item2", "key1")
59
 
False
60
 
>>> g["key2"]
61
 
{1: 'item1', 2: 'item2'}
62
 
>>> g.add("key3", 1, "item1", "key1")
63
 
False
64
 
>>> g.add("key3", 1, "item1", "key2")
65
 
True
66
 
>>> g.ordered_keys()
67
 
['key3', 'key2', 'key1']
68
 
 
69
 
>>> g.add("key2", 1, "item1", "key3")
70
 
True
71
 
>>> g.ordered_keys()
72
 
Traceback (most recent call last):
73
 
    ...
74
 
CyclicDependency: There is a cyclic dependency of items to be processed.
75
 
 
76
 
 
77
 
## Second, test the usage of CollectedObjects by Model.delete()
78
 
 
79
 
# Due to the way that transactions work in the test harness,
80
 
# doing m.delete() here can work but fail in a real situation,
81
 
# since it may delete all objects, but not in the right order.
82
 
# So we manually check that the order of deletion is correct.
83
 
 
84
 
# Also, it is possible that the order is correct 'accidentally', due
85
 
# solely to order of imports etc.  To check this, we set the order
86
 
# that 'get_models()' will retrieve to a known 'nice' order, and
87
 
# then try again with a known 'tricky' order.  Slightly naughty
88
 
# access to internals here :-)
89
 
 
90
 
# If implementation changes, then the tests may need to be simplified:
91
 
#  - remove the lines that set the .keyOrder and clear the related
92
 
#    object caches
93
 
#  - remove the second set of tests (with a2, b2 etc)
94
 
 
95
 
>>> from django.db.models.loading import cache
96
 
 
97
 
>>> def clear_rel_obj_caches(models):
98
 
...     for m in models:
99
 
...         if hasattr(m._meta, '_related_objects_cache'): 
100
 
...             del m._meta._related_objects_cache
101
 
 
102
 
# Nice order
103
 
>>> cache.app_models['delete'].keyOrder = ['a', 'b', 'c', 'd']
104
 
>>> clear_rel_obj_caches([A, B, C, D])
105
 
 
106
 
>>> a1 = A()
107
 
>>> a1.save()
108
 
>>> b1 = B(a=a1)
109
 
>>> b1.save()
110
 
>>> c1 = C(b=b1)
111
 
>>> c1.save()
112
 
>>> d1 = D(c=c1, a=a1)
113
 
>>> d1.save()
114
 
 
115
 
>>> o = CollectedObjects()
116
 
>>> a1._collect_sub_objects(o)
117
 
>>> o.keys()
118
 
[<class 'modeltests.delete.models.D'>, <class 'modeltests.delete.models.C'>, <class 'modeltests.delete.models.B'>, <class 'modeltests.delete.models.A'>]
119
 
>>> a1.delete()
120
 
 
121
 
# Same again with a known bad order
122
 
>>> cache.app_models['delete'].keyOrder = ['d', 'c', 'b', 'a']
123
 
>>> clear_rel_obj_caches([A, B, C, D])
124
 
 
125
 
>>> a2 = A()
126
 
>>> a2.save()
127
 
>>> b2 = B(a=a2)
128
 
>>> b2.save()
129
 
>>> c2 = C(b=b2)
130
 
>>> c2.save()
131
 
>>> d2 = D(c=c2, a=a2)
132
 
>>> d2.save()
133
 
 
134
 
>>> o = CollectedObjects()
135
 
>>> a2._collect_sub_objects(o)
136
 
>>> o.keys()
137
 
[<class 'modeltests.delete.models.D'>, <class 'modeltests.delete.models.C'>, <class 'modeltests.delete.models.B'>, <class 'modeltests.delete.models.A'>]
138
 
>>> a2.delete()
139
 
 
140
 
### Tests for models E,F - nullable related fields ###
141
 
 
142
 
## First, test the CollectedObjects data structure directly
143
 
 
144
 
>>> g = CollectedObjects()
145
 
>>> g.add("key1", 1, "item1", None)
146
 
False
147
 
>>> g.add("key2", 1, "item1", "key1", nullable=True)
148
 
False
149
 
>>> g.add("key1", 1, "item1", "key2")
150
 
True
151
 
>>> g.ordered_keys()
152
 
['key1', 'key2']
153
 
 
154
 
## Second, test the usage of CollectedObjects by Model.delete()
155
 
 
156
 
>>> e1 = E()
157
 
>>> e1.save()
158
 
>>> f1 = F(e=e1)
159
 
>>> f1.save()
160
 
>>> e1.f = f1
161
 
>>> e1.save()
162
 
 
163
 
# Since E.f is nullable, we should delete F first (after nulling out
164
 
# the E.f field), then E.
165
 
 
166
 
>>> o = CollectedObjects()
167
 
>>> e1._collect_sub_objects(o)
168
 
>>> o.keys()
169
 
[<class 'modeltests.delete.models.F'>, <class 'modeltests.delete.models.E'>]
170
 
 
171
 
>>> e1.delete()
172
 
 
173
 
>>> e2 = E()
174
 
>>> e2.save()
175
 
>>> f2 = F(e=e2)
176
 
>>> f2.save()
177
 
>>> e2.f = f2
178
 
>>> e2.save()
179
 
 
180
 
# Same deal as before, though we are starting from the other object.
181
 
 
182
 
>>> o = CollectedObjects()
183
 
>>> f2._collect_sub_objects(o)
184
 
>>> o.keys()
185
 
[<class 'modeltests.delete.models.F'>, <class 'modeltests.delete.models.E'>]
186
 
 
187
 
>>> f2.delete()
188
 
 
189
 
"""
190
 
}