|
1 """ |
|
2 Various complex queries that have been problematic in the past. |
|
3 """ |
|
4 |
|
5 import threading |
|
6 |
|
7 from django.db import models |
|
8 |
|
9 class DumbCategory(models.Model): |
|
10 pass |
|
11 |
|
12 class NamedCategory(DumbCategory): |
|
13 name = models.CharField(max_length=10) |
|
14 |
|
15 class Tag(models.Model): |
|
16 name = models.CharField(max_length=10) |
|
17 parent = models.ForeignKey('self', blank=True, null=True, |
|
18 related_name='children') |
|
19 category = models.ForeignKey(NamedCategory, null=True, default=None) |
|
20 |
|
21 class Meta: |
|
22 ordering = ['name'] |
|
23 |
|
24 def __unicode__(self): |
|
25 return self.name |
|
26 |
|
27 class Note(models.Model): |
|
28 note = models.CharField(max_length=100) |
|
29 misc = models.CharField(max_length=10) |
|
30 |
|
31 class Meta: |
|
32 ordering = ['note'] |
|
33 |
|
34 def __unicode__(self): |
|
35 return self.note |
|
36 |
|
37 def __init__(self, *args, **kwargs): |
|
38 super(Note, self).__init__(*args, **kwargs) |
|
39 # Regression for #13227 -- having an attribute that |
|
40 # is unpickleable doesn't stop you from cloning queries |
|
41 # that use objects of that type as an argument. |
|
42 self.lock = threading.Lock() |
|
43 |
|
44 class Annotation(models.Model): |
|
45 name = models.CharField(max_length=10) |
|
46 tag = models.ForeignKey(Tag) |
|
47 notes = models.ManyToManyField(Note) |
|
48 |
|
49 def __unicode__(self): |
|
50 return self.name |
|
51 |
|
52 class ExtraInfo(models.Model): |
|
53 info = models.CharField(max_length=100) |
|
54 note = models.ForeignKey(Note) |
|
55 |
|
56 class Meta: |
|
57 ordering = ['info'] |
|
58 |
|
59 def __unicode__(self): |
|
60 return self.info |
|
61 |
|
62 class Author(models.Model): |
|
63 name = models.CharField(max_length=10) |
|
64 num = models.IntegerField(unique=True) |
|
65 extra = models.ForeignKey(ExtraInfo) |
|
66 |
|
67 class Meta: |
|
68 ordering = ['name'] |
|
69 |
|
70 def __unicode__(self): |
|
71 return self.name |
|
72 |
|
73 class Item(models.Model): |
|
74 name = models.CharField(max_length=10) |
|
75 created = models.DateTimeField() |
|
76 modified = models.DateTimeField(blank=True, null=True) |
|
77 tags = models.ManyToManyField(Tag, blank=True, null=True) |
|
78 creator = models.ForeignKey(Author) |
|
79 note = models.ForeignKey(Note) |
|
80 |
|
81 class Meta: |
|
82 ordering = ['-note', 'name'] |
|
83 |
|
84 def __unicode__(self): |
|
85 return self.name |
|
86 |
|
87 class Report(models.Model): |
|
88 name = models.CharField(max_length=10) |
|
89 creator = models.ForeignKey(Author, to_field='num', null=True) |
|
90 |
|
91 def __unicode__(self): |
|
92 return self.name |
|
93 |
|
94 class Ranking(models.Model): |
|
95 rank = models.IntegerField() |
|
96 author = models.ForeignKey(Author) |
|
97 |
|
98 class Meta: |
|
99 # A complex ordering specification. Should stress the system a bit. |
|
100 ordering = ('author__extra__note', 'author__name', 'rank') |
|
101 |
|
102 def __unicode__(self): |
|
103 return '%d: %s' % (self.rank, self.author.name) |
|
104 |
|
105 class Cover(models.Model): |
|
106 title = models.CharField(max_length=50) |
|
107 item = models.ForeignKey(Item) |
|
108 |
|
109 class Meta: |
|
110 ordering = ['item'] |
|
111 |
|
112 def __unicode__(self): |
|
113 return self.title |
|
114 |
|
115 class Number(models.Model): |
|
116 num = models.IntegerField() |
|
117 |
|
118 def __unicode__(self): |
|
119 return unicode(self.num) |
|
120 |
|
121 # Symmetrical m2m field with a normal field using the reverse accesor name |
|
122 # ("valid"). |
|
123 class Valid(models.Model): |
|
124 valid = models.CharField(max_length=10) |
|
125 parent = models.ManyToManyField('self') |
|
126 |
|
127 class Meta: |
|
128 ordering = ['valid'] |
|
129 |
|
130 # Some funky cross-linked models for testing a couple of infinite recursion |
|
131 # cases. |
|
132 class X(models.Model): |
|
133 y = models.ForeignKey('Y') |
|
134 |
|
135 class Y(models.Model): |
|
136 x1 = models.ForeignKey(X, related_name='y1') |
|
137 |
|
138 # Some models with a cycle in the default ordering. This would be bad if we |
|
139 # didn't catch the infinite loop. |
|
140 class LoopX(models.Model): |
|
141 y = models.ForeignKey('LoopY') |
|
142 |
|
143 class Meta: |
|
144 ordering = ['y'] |
|
145 |
|
146 class LoopY(models.Model): |
|
147 x = models.ForeignKey(LoopX) |
|
148 |
|
149 class Meta: |
|
150 ordering = ['x'] |
|
151 |
|
152 class LoopZ(models.Model): |
|
153 z = models.ForeignKey('self') |
|
154 |
|
155 class Meta: |
|
156 ordering = ['z'] |
|
157 |
|
158 # A model and custom default manager combination. |
|
159 class CustomManager(models.Manager): |
|
160 def get_query_set(self): |
|
161 qs = super(CustomManager, self).get_query_set() |
|
162 return qs.filter(public=True, tag__name='t1') |
|
163 |
|
164 class ManagedModel(models.Model): |
|
165 data = models.CharField(max_length=10) |
|
166 tag = models.ForeignKey(Tag) |
|
167 public = models.BooleanField(default=True) |
|
168 |
|
169 objects = CustomManager() |
|
170 normal_manager = models.Manager() |
|
171 |
|
172 def __unicode__(self): |
|
173 return self.data |
|
174 |
|
175 # An inter-related setup with multiple paths from Child to Detail. |
|
176 class Detail(models.Model): |
|
177 data = models.CharField(max_length=10) |
|
178 |
|
179 class MemberManager(models.Manager): |
|
180 def get_query_set(self): |
|
181 return super(MemberManager, self).get_query_set().select_related("details") |
|
182 |
|
183 class Member(models.Model): |
|
184 name = models.CharField(max_length=10) |
|
185 details = models.OneToOneField(Detail, primary_key=True) |
|
186 |
|
187 objects = MemberManager() |
|
188 |
|
189 class Child(models.Model): |
|
190 person = models.OneToOneField(Member, primary_key=True) |
|
191 parent = models.ForeignKey(Member, related_name="children") |
|
192 |
|
193 # Custom primary keys interfered with ordering in the past. |
|
194 class CustomPk(models.Model): |
|
195 name = models.CharField(max_length=10, primary_key=True) |
|
196 extra = models.CharField(max_length=10) |
|
197 |
|
198 class Meta: |
|
199 ordering = ['name', 'extra'] |
|
200 |
|
201 class Related(models.Model): |
|
202 custom = models.ForeignKey(CustomPk) |
|
203 |
|
204 # An inter-related setup with a model subclass that has a nullable |
|
205 # path to another model, and a return path from that model. |
|
206 |
|
207 class Celebrity(models.Model): |
|
208 name = models.CharField("Name", max_length=20) |
|
209 greatest_fan = models.ForeignKey("Fan", null=True, unique=True) |
|
210 |
|
211 class TvChef(Celebrity): |
|
212 pass |
|
213 |
|
214 class Fan(models.Model): |
|
215 fan_of = models.ForeignKey(Celebrity) |
|
216 |
|
217 # Multiple foreign keys |
|
218 class LeafA(models.Model): |
|
219 data = models.CharField(max_length=10) |
|
220 |
|
221 def __unicode__(self): |
|
222 return self.data |
|
223 |
|
224 class LeafB(models.Model): |
|
225 data = models.CharField(max_length=10) |
|
226 |
|
227 class Join(models.Model): |
|
228 a = models.ForeignKey(LeafA) |
|
229 b = models.ForeignKey(LeafB) |
|
230 |
|
231 class ReservedName(models.Model): |
|
232 name = models.CharField(max_length=20) |
|
233 order = models.IntegerField() |
|
234 |
|
235 def __unicode__(self): |
|
236 return self.name |
|
237 |
|
238 # A simpler shared-foreign-key setup that can expose some problems. |
|
239 class SharedConnection(models.Model): |
|
240 data = models.CharField(max_length=10) |
|
241 |
|
242 class PointerA(models.Model): |
|
243 connection = models.ForeignKey(SharedConnection) |
|
244 |
|
245 class PointerB(models.Model): |
|
246 connection = models.ForeignKey(SharedConnection) |
|
247 |
|
248 # Multi-layer ordering |
|
249 class SingleObject(models.Model): |
|
250 name = models.CharField(max_length=10) |
|
251 |
|
252 class Meta: |
|
253 ordering = ['name'] |
|
254 |
|
255 def __unicode__(self): |
|
256 return self.name |
|
257 |
|
258 class RelatedObject(models.Model): |
|
259 single = models.ForeignKey(SingleObject) |
|
260 |
|
261 class Meta: |
|
262 ordering = ['single'] |
|
263 |
|
264 class Plaything(models.Model): |
|
265 name = models.CharField(max_length=10) |
|
266 others = models.ForeignKey(RelatedObject, null=True) |
|
267 |
|
268 class Meta: |
|
269 ordering = ['others'] |
|
270 |
|
271 def __unicode__(self): |
|
272 return self.name |
|
273 |
|
274 class Article(models.Model): |
|
275 name = models.CharField(max_length=20) |
|
276 created = models.DateTimeField() |