33from django .core .exceptions import FieldError
44from django .db import connection
55from django .test import TestCase , skipUnlessDBFeature
6- from models import Article
6+ from models import Author , Article , Tag
77
88
99class LookupTests (TestCase ):
1010
1111 #def setUp(self):
1212 def setUp (self ):
13+ # Create a few Authors.
14+ self .au1 = Author (name = 'Author 1' )
15+ self .au1 .save ()
16+ self .au2 = Author (name = 'Author 2' )
17+ self .au2 .save ()
1318 # Create a couple of Articles.
14- self .a1 = Article (headline = 'Article 1' , pub_date = datetime (2005 , 7 , 26 ))
19+ self .a1 = Article (headline = 'Article 1' , pub_date = datetime (2005 , 7 , 26 ), author = self . au1 )
1520 self .a1 .save ()
16- self .a2 = Article (headline = 'Article 2' , pub_date = datetime (2005 , 7 , 27 ))
21+ self .a2 = Article (headline = 'Article 2' , pub_date = datetime (2005 , 7 , 27 ), author = self . au1 )
1722 self .a2 .save ()
18- self .a3 = Article (headline = 'Article 3' , pub_date = datetime (2005 , 7 , 27 ))
23+ self .a3 = Article (headline = 'Article 3' , pub_date = datetime (2005 , 7 , 27 ), author = self . au1 )
1924 self .a3 .save ()
20- self .a4 = Article (headline = 'Article 4' , pub_date = datetime (2005 , 7 , 28 ))
25+ self .a4 = Article (headline = 'Article 4' , pub_date = datetime (2005 , 7 , 28 ), author = self . au1 )
2126 self .a4 .save ()
22- self .a5 = Article (headline = 'Article 5' , pub_date = datetime (2005 , 8 , 1 , 9 , 0 ))
27+ self .a5 = Article (headline = 'Article 5' , pub_date = datetime (2005 , 8 , 1 , 9 , 0 ), author = self . au2 )
2328 self .a5 .save ()
24- self .a6 = Article (headline = 'Article 6' , pub_date = datetime (2005 , 8 , 1 , 8 , 0 ))
29+ self .a6 = Article (headline = 'Article 6' , pub_date = datetime (2005 , 8 , 1 , 8 , 0 ), author = self . au2 )
2530 self .a6 .save ()
26- self .a7 = Article (headline = 'Article 7' , pub_date = datetime (2005 , 7 , 27 ))
31+ self .a7 = Article (headline = 'Article 7' , pub_date = datetime (2005 , 7 , 27 ), author = self . au2 )
2732 self .a7 .save ()
33+ # Create a few Tags.
34+ self .t1 = Tag (name = 'Tag 1' )
35+ self .t1 .save ()
36+ self .t1 .articles .add (self .a1 , self .a2 , self .a3 )
37+ self .t2 = Tag (name = 'Tag 2' )
38+ self .t2 .save ()
39+ self .t2 .articles .add (self .a3 , self .a4 , self .a5 )
40+ self .t3 = Tag (name = 'Tag 3' )
41+ self .t3 .save ()
42+ self .t3 .articles .add (self .a5 , self .a6 , self .a7 )
2843
2944 def test_exists (self ):
3045 # We can use .exists() to check that there are some
@@ -182,6 +197,42 @@ def test_values(self):
182197 'id_plus_seven' : self .a1 .id + 7 ,
183198 'id_plus_eight' : self .a1 .id + 8 ,
184199 }], transform = identity )
200+ # You can specify fields from forward and reverse relations, just like filter().
201+ self .assertQuerysetEqual (
202+ Article .objects .values ('headline' , 'author__name' ),
203+ [
204+ {'headline' : self .a5 .headline , 'author__name' : self .au2 .name },
205+ {'headline' : self .a6 .headline , 'author__name' : self .au2 .name },
206+ {'headline' : self .a4 .headline , 'author__name' : self .au1 .name },
207+ {'headline' : self .a2 .headline , 'author__name' : self .au1 .name },
208+ {'headline' : self .a3 .headline , 'author__name' : self .au1 .name },
209+ {'headline' : self .a7 .headline , 'author__name' : self .au2 .name },
210+ {'headline' : self .a1 .headline , 'author__name' : self .au1 .name },
211+ ], transform = identity )
212+ self .assertQuerysetEqual (
213+ Author .objects .values ('name' , 'article__headline' ).order_by ('name' , 'article__headline' ),
214+ [
215+ {'name' : self .au1 .name , 'article__headline' : self .a1 .headline },
216+ {'name' : self .au1 .name , 'article__headline' : self .a2 .headline },
217+ {'name' : self .au1 .name , 'article__headline' : self .a3 .headline },
218+ {'name' : self .au1 .name , 'article__headline' : self .a4 .headline },
219+ {'name' : self .au2 .name , 'article__headline' : self .a5 .headline },
220+ {'name' : self .au2 .name , 'article__headline' : self .a6 .headline },
221+ {'name' : self .au2 .name , 'article__headline' : self .a7 .headline },
222+ ], transform = identity )
223+ self .assertQuerysetEqual (
224+ Author .objects .values ('name' , 'article__headline' , 'article__tag__name' ).order_by ('name' , 'article__headline' , 'article__tag__name' ),
225+ [
226+ {'name' : self .au1 .name , 'article__headline' : self .a1 .headline , 'article__tag__name' : self .t1 .name },
227+ {'name' : self .au1 .name , 'article__headline' : self .a2 .headline , 'article__tag__name' : self .t1 .name },
228+ {'name' : self .au1 .name , 'article__headline' : self .a3 .headline , 'article__tag__name' : self .t1 .name },
229+ {'name' : self .au1 .name , 'article__headline' : self .a3 .headline , 'article__tag__name' : self .t2 .name },
230+ {'name' : self .au1 .name , 'article__headline' : self .a4 .headline , 'article__tag__name' : self .t2 .name },
231+ {'name' : self .au2 .name , 'article__headline' : self .a5 .headline , 'article__tag__name' : self .t2 .name },
232+ {'name' : self .au2 .name , 'article__headline' : self .a5 .headline , 'article__tag__name' : self .t3 .name },
233+ {'name' : self .au2 .name , 'article__headline' : self .a6 .headline , 'article__tag__name' : self .t3 .name },
234+ {'name' : self .au2 .name , 'article__headline' : self .a7 .headline , 'article__tag__name' : self .t3 .name },
235+ ], transform = identity )
185236 # However, an exception FieldDoesNotExist will be thrown if you specify
186237 # a non-existent field name in values() (a field that is neither in the
187238 # model nor in extra(select)).
@@ -192,6 +243,7 @@ def test_values(self):
192243 self .assertQuerysetEqual (Article .objects .filter (id = self .a5 .id ).values (),
193244 [{
194245 'id' : self .a5 .id ,
246+ 'author_id' : self .au2 .id ,
195247 'headline' : 'Article 5' ,
196248 'pub_date' : datetime (2005 , 8 , 1 , 9 , 0 )
197249 }], transform = identity )
@@ -250,6 +302,19 @@ def test_values_list(self):
250302 (self .a7 .id , self .a7 .id + 1 )
251303 ],
252304 transform = identity )
305+ self .assertQuerysetEqual (
306+ Author .objects .values_list ('name' , 'article__headline' , 'article__tag__name' ).order_by ('name' , 'article__headline' , 'article__tag__name' ),
307+ [
308+ (self .au1 .name , self .a1 .headline , self .t1 .name ),
309+ (self .au1 .name , self .a2 .headline , self .t1 .name ),
310+ (self .au1 .name , self .a3 .headline , self .t1 .name ),
311+ (self .au1 .name , self .a3 .headline , self .t2 .name ),
312+ (self .au1 .name , self .a4 .headline , self .t2 .name ),
313+ (self .au2 .name , self .a5 .headline , self .t2 .name ),
314+ (self .au2 .name , self .a5 .headline , self .t3 .name ),
315+ (self .au2 .name , self .a6 .headline , self .t3 .name ),
316+ (self .au2 .name , self .a7 .headline , self .t3 .name ),
317+ ], transform = identity )
253318 self .assertRaises (TypeError , Article .objects .values_list , 'id' , 'headline' , flat = True )
254319
255320 def test_get_next_previous_by (self ):
@@ -402,7 +467,7 @@ def test_error_messages(self):
402467 self .fail ('FieldError not raised' )
403468 except FieldError , ex :
404469 self .assertEqual (str (ex ), "Cannot resolve keyword 'pub_date_year' "
405- "into field. Choices are: headline, id, pub_date" )
470+ "into field. Choices are: author, headline, id, pub_date, tag " )
406471 try :
407472 Article .objects .filter (headline__starts = 'Article' )
408473 self .fail ('FieldError not raised' )
0 commit comments