|
1 """ |
|
2 1. Bare-bones model |
|
3 |
|
4 This is a basic model with only two non-primary-key fields. |
|
5 """ |
|
6 |
|
7 from django.db import models |
|
8 |
|
9 class Article(models.Model): |
|
10 headline = models.CharField(maxlength=100, default='Default headline') |
|
11 pub_date = models.DateTimeField() |
|
12 |
|
13 class Meta: |
|
14 ordering = ('pub_date','headline') |
|
15 |
|
16 def __str__(self): |
|
17 return self.headline |
|
18 |
|
19 __test__ = {'API_TESTS': """ |
|
20 # No articles are in the system yet. |
|
21 >>> Article.objects.all() |
|
22 [] |
|
23 |
|
24 # Create an Article. |
|
25 >>> from datetime import datetime |
|
26 >>> a = Article(id=None, headline='Area man programs in Python', pub_date=datetime(2005, 7, 28)) |
|
27 |
|
28 # Save it into the database. You have to call save() explicitly. |
|
29 >>> a.save() |
|
30 |
|
31 # Now it has an ID. Note it's a long integer, as designated by the trailing "L". |
|
32 >>> a.id |
|
33 1L |
|
34 |
|
35 # Access database columns via Python attributes. |
|
36 >>> a.headline |
|
37 'Area man programs in Python' |
|
38 >>> a.pub_date |
|
39 datetime.datetime(2005, 7, 28, 0, 0) |
|
40 |
|
41 # Change values by changing the attributes, then calling save(). |
|
42 >>> a.headline = 'Area woman programs in Python' |
|
43 >>> a.save() |
|
44 |
|
45 # Article.objects.all() returns all the articles in the database. |
|
46 >>> Article.objects.all() |
|
47 [<Article: Area woman programs in Python>] |
|
48 |
|
49 # Django provides a rich database lookup API. |
|
50 >>> Article.objects.get(id__exact=1) |
|
51 <Article: Area woman programs in Python> |
|
52 >>> Article.objects.get(headline__startswith='Area woman') |
|
53 <Article: Area woman programs in Python> |
|
54 >>> Article.objects.get(pub_date__year=2005) |
|
55 <Article: Area woman programs in Python> |
|
56 >>> Article.objects.get(pub_date__year=2005, pub_date__month=7) |
|
57 <Article: Area woman programs in Python> |
|
58 >>> Article.objects.get(pub_date__year=2005, pub_date__month=7, pub_date__day=28) |
|
59 <Article: Area woman programs in Python> |
|
60 |
|
61 # The "__exact" lookup type can be omitted, as a shortcut. |
|
62 >>> Article.objects.get(id=1) |
|
63 <Article: Area woman programs in Python> |
|
64 >>> Article.objects.get(headline='Area woman programs in Python') |
|
65 <Article: Area woman programs in Python> |
|
66 |
|
67 >>> Article.objects.filter(pub_date__year=2005) |
|
68 [<Article: Area woman programs in Python>] |
|
69 >>> Article.objects.filter(pub_date__year=2004) |
|
70 [] |
|
71 >>> Article.objects.filter(pub_date__year=2005, pub_date__month=7) |
|
72 [<Article: Area woman programs in Python>] |
|
73 |
|
74 # Django raises an Article.DoesNotExist exception for get() if the parameters |
|
75 # don't match any object. |
|
76 >>> Article.objects.get(id__exact=2) |
|
77 Traceback (most recent call last): |
|
78 ... |
|
79 DoesNotExist: Article matching query does not exist. |
|
80 |
|
81 >>> Article.objects.get(pub_date__year=2005, pub_date__month=8) |
|
82 Traceback (most recent call last): |
|
83 ... |
|
84 DoesNotExist: Article matching query does not exist. |
|
85 |
|
86 # Lookup by a primary key is the most common case, so Django provides a |
|
87 # shortcut for primary-key exact lookups. |
|
88 # The following is identical to articles.get(id=1). |
|
89 >>> Article.objects.get(pk=1) |
|
90 <Article: Area woman programs in Python> |
|
91 |
|
92 # pk can be used as a shortcut for the primary key name in any query |
|
93 >>> Article.objects.filter(pk__in=[1]) |
|
94 [<Article: Area woman programs in Python>] |
|
95 |
|
96 # Model instances of the same type and same ID are considered equal. |
|
97 >>> a = Article.objects.get(pk=1) |
|
98 >>> b = Article.objects.get(pk=1) |
|
99 >>> a == b |
|
100 True |
|
101 |
|
102 # You can initialize a model instance using positional arguments, which should |
|
103 # match the field order as defined in the model. |
|
104 >>> a2 = Article(None, 'Second article', datetime(2005, 7, 29)) |
|
105 >>> a2.save() |
|
106 >>> a2.id |
|
107 2L |
|
108 >>> a2.headline |
|
109 'Second article' |
|
110 >>> a2.pub_date |
|
111 datetime.datetime(2005, 7, 29, 0, 0) |
|
112 |
|
113 # ...or, you can use keyword arguments. |
|
114 >>> a3 = Article(id=None, headline='Third article', pub_date=datetime(2005, 7, 30)) |
|
115 >>> a3.save() |
|
116 >>> a3.id |
|
117 3L |
|
118 >>> a3.headline |
|
119 'Third article' |
|
120 >>> a3.pub_date |
|
121 datetime.datetime(2005, 7, 30, 0, 0) |
|
122 |
|
123 # You can also mix and match position and keyword arguments, but be sure not to |
|
124 # duplicate field information. |
|
125 >>> a4 = Article(None, 'Fourth article', pub_date=datetime(2005, 7, 31)) |
|
126 >>> a4.save() |
|
127 >>> a4.headline |
|
128 'Fourth article' |
|
129 |
|
130 # Don't use invalid keyword arguments. |
|
131 >>> a5 = Article(id=None, headline='Invalid', pub_date=datetime(2005, 7, 31), foo='bar') |
|
132 Traceback (most recent call last): |
|
133 ... |
|
134 TypeError: 'foo' is an invalid keyword argument for this function |
|
135 |
|
136 # You can leave off the value for an AutoField when creating an object, because |
|
137 # it'll get filled in automatically when you save(). |
|
138 >>> a5 = Article(headline='Article 6', pub_date=datetime(2005, 7, 31)) |
|
139 >>> a5.save() |
|
140 >>> a5.id |
|
141 5L |
|
142 >>> a5.headline |
|
143 'Article 6' |
|
144 |
|
145 # If you leave off a field with "default" set, Django will use the default. |
|
146 >>> a6 = Article(pub_date=datetime(2005, 7, 31)) |
|
147 >>> a6.save() |
|
148 >>> a6.headline |
|
149 'Default headline' |
|
150 |
|
151 # For DateTimeFields, Django saves as much precision (in seconds) as you |
|
152 # give it. |
|
153 >>> a7 = Article(headline='Article 7', pub_date=datetime(2005, 7, 31, 12, 30)) |
|
154 >>> a7.save() |
|
155 >>> Article.objects.get(id__exact=7).pub_date |
|
156 datetime.datetime(2005, 7, 31, 12, 30) |
|
157 |
|
158 >>> a8 = Article(headline='Article 8', pub_date=datetime(2005, 7, 31, 12, 30, 45)) |
|
159 >>> a8.save() |
|
160 >>> Article.objects.get(id__exact=8).pub_date |
|
161 datetime.datetime(2005, 7, 31, 12, 30, 45) |
|
162 >>> a8.id |
|
163 8L |
|
164 |
|
165 # Saving an object again doesn't create a new object -- it just saves the old one. |
|
166 >>> a8.save() |
|
167 >>> a8.id |
|
168 8L |
|
169 >>> a8.headline = 'Updated article 8' |
|
170 >>> a8.save() |
|
171 >>> a8.id |
|
172 8L |
|
173 |
|
174 >>> a7 == a8 |
|
175 False |
|
176 >>> a8 == Article.objects.get(id__exact=8) |
|
177 True |
|
178 >>> a7 != a8 |
|
179 True |
|
180 >>> Article.objects.get(id__exact=8) != Article.objects.get(id__exact=7) |
|
181 True |
|
182 >>> Article.objects.get(id__exact=8) == Article.objects.get(id__exact=7) |
|
183 False |
|
184 |
|
185 # dates() returns a list of available dates of the given scope for the given field. |
|
186 >>> Article.objects.dates('pub_date', 'year') |
|
187 [datetime.datetime(2005, 1, 1, 0, 0)] |
|
188 >>> Article.objects.dates('pub_date', 'month') |
|
189 [datetime.datetime(2005, 7, 1, 0, 0)] |
|
190 >>> Article.objects.dates('pub_date', 'day') |
|
191 [datetime.datetime(2005, 7, 28, 0, 0), datetime.datetime(2005, 7, 29, 0, 0), datetime.datetime(2005, 7, 30, 0, 0), datetime.datetime(2005, 7, 31, 0, 0)] |
|
192 >>> Article.objects.dates('pub_date', 'day', order='ASC') |
|
193 [datetime.datetime(2005, 7, 28, 0, 0), datetime.datetime(2005, 7, 29, 0, 0), datetime.datetime(2005, 7, 30, 0, 0), datetime.datetime(2005, 7, 31, 0, 0)] |
|
194 >>> Article.objects.dates('pub_date', 'day', order='DESC') |
|
195 [datetime.datetime(2005, 7, 31, 0, 0), datetime.datetime(2005, 7, 30, 0, 0), datetime.datetime(2005, 7, 29, 0, 0), datetime.datetime(2005, 7, 28, 0, 0)] |
|
196 |
|
197 # dates() requires valid arguments. |
|
198 |
|
199 >>> Article.objects.dates() |
|
200 Traceback (most recent call last): |
|
201 ... |
|
202 TypeError: dates() takes at least 3 arguments (1 given) |
|
203 |
|
204 >>> Article.objects.dates('invalid_field', 'year') |
|
205 Traceback (most recent call last): |
|
206 ... |
|
207 FieldDoesNotExist: Article has no field named 'invalid_field' |
|
208 |
|
209 >>> Article.objects.dates('pub_date', 'bad_kind') |
|
210 Traceback (most recent call last): |
|
211 ... |
|
212 AssertionError: 'kind' must be one of 'year', 'month' or 'day'. |
|
213 |
|
214 >>> Article.objects.dates('pub_date', 'year', order='bad order') |
|
215 Traceback (most recent call last): |
|
216 ... |
|
217 AssertionError: 'order' must be either 'ASC' or 'DESC'. |
|
218 |
|
219 # Use iterator() with dates() to return a generator that lazily requests each |
|
220 # result one at a time, to save memory. |
|
221 >>> for a in Article.objects.dates('pub_date', 'day', order='DESC').iterator(): |
|
222 ... print repr(a) |
|
223 datetime.datetime(2005, 7, 31, 0, 0) |
|
224 datetime.datetime(2005, 7, 30, 0, 0) |
|
225 datetime.datetime(2005, 7, 29, 0, 0) |
|
226 datetime.datetime(2005, 7, 28, 0, 0) |
|
227 |
|
228 # You can combine queries with & and |. |
|
229 >>> s1 = Article.objects.filter(id__exact=1) |
|
230 >>> s2 = Article.objects.filter(id__exact=2) |
|
231 >>> s1 | s2 |
|
232 [<Article: Area woman programs in Python>, <Article: Second article>] |
|
233 >>> s1 & s2 |
|
234 [] |
|
235 |
|
236 # You can get the number of objects like this: |
|
237 >>> len(Article.objects.filter(id__exact=1)) |
|
238 1 |
|
239 |
|
240 # You can get items using index and slice notation. |
|
241 >>> Article.objects.all()[0] |
|
242 <Article: Area woman programs in Python> |
|
243 >>> Article.objects.all()[1:3] |
|
244 [<Article: Second article>, <Article: Third article>] |
|
245 >>> s3 = Article.objects.filter(id__exact=3) |
|
246 >>> (s1 | s2 | s3)[::2] |
|
247 [<Article: Area woman programs in Python>, <Article: Third article>] |
|
248 |
|
249 # Slices (without step) are lazy: |
|
250 >>> Article.objects.all()[0:5].filter() |
|
251 [<Article: Area woman programs in Python>, <Article: Second article>, <Article: Third article>, <Article: Article 6>, <Article: Default headline>] |
|
252 |
|
253 # Slicing again works: |
|
254 >>> Article.objects.all()[0:5][0:2] |
|
255 [<Article: Area woman programs in Python>, <Article: Second article>] |
|
256 >>> Article.objects.all()[0:5][:2] |
|
257 [<Article: Area woman programs in Python>, <Article: Second article>] |
|
258 >>> Article.objects.all()[0:5][4:] |
|
259 [<Article: Default headline>] |
|
260 >>> Article.objects.all()[0:5][5:] |
|
261 [] |
|
262 |
|
263 # Some more tests! |
|
264 >>> Article.objects.all()[2:][0:2] |
|
265 [<Article: Third article>, <Article: Article 6>] |
|
266 >>> Article.objects.all()[2:][:2] |
|
267 [<Article: Third article>, <Article: Article 6>] |
|
268 >>> Article.objects.all()[2:][2:3] |
|
269 [<Article: Default headline>] |
|
270 |
|
271 # Note that you can't use 'offset' without 'limit' (on some dbs), so this doesn't work: |
|
272 >>> Article.objects.all()[2:] |
|
273 Traceback (most recent call last): |
|
274 ... |
|
275 AssertionError: 'offset' is not allowed without 'limit' |
|
276 |
|
277 # Also, once you have sliced you can't filter, re-order or combine |
|
278 >>> Article.objects.all()[0:5].filter(id=1) |
|
279 Traceback (most recent call last): |
|
280 ... |
|
281 AssertionError: Cannot filter a query once a slice has been taken. |
|
282 |
|
283 >>> Article.objects.all()[0:5].order_by('id') |
|
284 Traceback (most recent call last): |
|
285 ... |
|
286 AssertionError: Cannot reorder a query once a slice has been taken. |
|
287 |
|
288 >>> Article.objects.all()[0:1] & Article.objects.all()[4:5] |
|
289 Traceback (most recent call last): |
|
290 ... |
|
291 AssertionError: Cannot combine queries once a slice has been taken. |
|
292 |
|
293 # Negative slices are not supported, due to database constraints. |
|
294 # (hint: inverting your ordering might do what you need). |
|
295 >>> Article.objects.all()[-1] |
|
296 Traceback (most recent call last): |
|
297 ... |
|
298 AssertionError: Negative indexing is not supported. |
|
299 >>> Article.objects.all()[0:-5] |
|
300 Traceback (most recent call last): |
|
301 ... |
|
302 AssertionError: Negative indexing is not supported. |
|
303 |
|
304 # An Article instance doesn't have access to the "objects" attribute. |
|
305 # That's only available on the class. |
|
306 >>> a7.objects.all() |
|
307 Traceback (most recent call last): |
|
308 ... |
|
309 AttributeError: Manager isn't accessible via Article instances |
|
310 |
|
311 >>> a7.objects |
|
312 Traceback (most recent call last): |
|
313 ... |
|
314 AttributeError: Manager isn't accessible via Article instances |
|
315 |
|
316 # Bulk delete test: How many objects before and after the delete? |
|
317 >>> Article.objects.all() |
|
318 [<Article: Area woman programs in Python>, <Article: Second article>, <Article: Third article>, <Article: Article 6>, <Article: Default headline>, <Article: Fourth article>, <Article: Article 7>, <Article: Updated article 8>] |
|
319 >>> Article.objects.filter(id__lte=4).delete() |
|
320 >>> Article.objects.all() |
|
321 [<Article: Article 6>, <Article: Default headline>, <Article: Article 7>, <Article: Updated article 8>] |
|
322 """} |
|
323 |
|
324 from django.conf import settings |
|
325 |
|
326 building_docs = getattr(settings, 'BUILDING_DOCS', False) |
|
327 |
|
328 if building_docs or settings.DATABASE_ENGINE == 'postgresql': |
|
329 __test__['API_TESTS'] += """ |
|
330 # In PostgreSQL, microsecond-level precision is available. |
|
331 >>> a9 = Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180)) |
|
332 >>> a9.save() |
|
333 >>> Article.objects.get(id__exact=9).pub_date |
|
334 datetime.datetime(2005, 7, 31, 12, 30, 45, 180) |
|
335 """ |
|
336 |
|
337 if building_docs or settings.DATABASE_ENGINE == 'mysql': |
|
338 __test__['API_TESTS'] += """ |
|
339 # In MySQL, microsecond-level precision isn't available. You'll lose |
|
340 # microsecond-level precision once the data is saved. |
|
341 >>> a9 = Article(headline='Article 9', pub_date=datetime(2005, 7, 31, 12, 30, 45, 180)) |
|
342 >>> a9.save() |
|
343 >>> Article.objects.get(id__exact=9).pub_date |
|
344 datetime.datetime(2005, 7, 31, 12, 30, 45) |
|
345 """ |
|
346 |
|
347 __test__['API_TESTS'] += """ |
|
348 |
|
349 # You can manually specify the primary key when creating a new object. |
|
350 >>> a101 = Article(id=101, headline='Article 101', pub_date=datetime(2005, 7, 31, 12, 30, 45)) |
|
351 >>> a101.save() |
|
352 >>> a101 = Article.objects.get(pk=101) |
|
353 >>> a101.headline |
|
354 'Article 101' |
|
355 |
|
356 # You can create saved objects in a single step |
|
357 >>> a10 = Article.objects.create(headline="Article 10", pub_date=datetime(2005, 7, 31, 12, 30, 45)) |
|
358 >>> Article.objects.get(headline="Article 10") |
|
359 <Article: Article 10> |
|
360 |
|
361 # Edge-case test: A year lookup should retrieve all objects in the given |
|
362 year, including Jan. 1 and Dec. 31. |
|
363 >>> a11 = Article.objects.create(headline='Article 11', pub_date=datetime(2008, 1, 1)) |
|
364 >>> a12 = Article.objects.create(headline='Article 12', pub_date=datetime(2008, 12, 31, 23, 59, 59, 999999)) |
|
365 >>> Article.objects.filter(pub_date__year=2008) |
|
366 [<Article: Article 11>, <Article: Article 12>] |
|
367 """ |