@@ -50,10 +50,12 @@ def setUp(self):
5050 publisher = mad_magazine , release = date (1990 , 8 , 14 ))
5151
5252 # Bob wrote a couple of books, an article, and a blog post.
53- Book .objects .create (title = "Fiction" , author = bob , publisher = big_books ,
54- pages = 10 , release = date (2001 , 6 , 12 ))
55- Book .objects .create (title = "Biography" , author = bob , publisher = big_books ,
56- pages = 20 , release = date (2002 , 12 , 24 ))
53+ book = Book .objects .create (title = "Fiction" , author = bob ,
54+ pages = 10 , release = date (2001 , 6 , 12 ))
55+ book .publishers .set ([big_books ])
56+ book = Book .objects .create (title = "Biography" , author = bob ,
57+ pages = 20 , release = date (2002 , 12 , 24 ))
58+ book .publishers .set ([big_books ])
5759 Article .objects .create (title = "Some Article" , author = bob ,
5860 publisher = mad_magazine , release = date (1979 , 1 , 1 ))
5961 BlogPost .objects .create (title = "Post" , author = bob ,
@@ -387,7 +389,7 @@ def test_empty_defer(self):
387389 def test_only (self ):
388390 """Only causes other fields to load on access (opposite of defer)."""
389391 with self .assertNumQueries (2 ):
390- books = list (self .all .only ('publisher ' ))
392+ books = list (self .all .only ('author ' ))
391393 with self .assertNumQueries (5 ):
392394 titles = [b .title for b in books ]
393395 self .assertEqual (titles , self .TITLES_BY_PK )
@@ -399,7 +401,7 @@ def test_order_by(self):
399401 # Additional queries are due to the field needing to be pulled
400402 # individually during sorting.
401403 with self .assertNumQueries (7 ):
402- books = list (self .all .only ('publisher ' ).order_by ('title' ))
404+ books = list (self .all .only ('author ' ).order_by ('title' ))
403405 # No additional queries are necessary since the titles were used in
404406 # sorting.
405407 with self .assertNumQueries (0 ):
@@ -421,14 +423,34 @@ def test_using(self):
421423
422424class TestDistinct (TestBase ):
423425 def test_distinct (self ):
424- for qs in self .all ._querysets :
425- assert not qs .query .distinct
426+ """
427+ Distinct gets applied to each QuerySet, but not the overall QuerySetSequence.
428+ """
429+ # Create another publisher and add an existing book to it.
430+ publisher = Publisher .objects .create (name = "Bigger Books" )
431+ book = Book .objects .get (title = "Biography" )
432+ book .publishers .add (publisher )
433+
434+ # Make a QuerySetSequence that would include non-distinct items.
435+ big_books = Book .objects .filter (publishers__name__startswith = "Big" )
436+ qss = QuerySetSequence (big_books , Article .objects .filter (publisher__name__startswith = "Big" ))
437+
438+ # There should be more items than unique items.
439+ titles = [b .title for b in qss ]
440+ self .assertGreater (len (titles ), len (set (titles )))
441+
426442 with self .assertNumQueries (0 ):
427- distinct = self .all .distinct ()
428- for qs in distinct ._querysets :
429- assert qs .query .distinct
443+ qss = qss .distinct ()
444+
445+ # After calling distinct there should not be duplicated entries.
446+ titles = [b .title for b in qss ]
447+ self .assertEqual (len (titles ), len (set (titles )))
430448
431449 def test_multiple_querysets_same_model (self ):
450+ """
451+ Calling distinct on a QuerySetSequence made up of multiple QuerySet instances
452+ of the same model is not supported.
453+ """
432454 qss = QuerySetSequence (Book .objects .all (), Book .objects .all ())
433455 with self .assertRaises (NotImplementedError ):
434456 qss .distinct ()
@@ -877,8 +899,7 @@ def test_order_by_multi(self):
877899 """Test ordering by multiple fields."""
878900 # Add another object with the same title, but a later release date.
879901 Book .objects .create (title = "Fiction" , author = self .alice ,
880- publisher = self .big_books , pages = 1 ,
881- release = date (2018 , 10 , 3 ))
902+ pages = 1 , release = date (2018 , 10 , 3 ))
882903
883904 with self .assertNumQueries (0 ):
884905 qss = self .all .order_by ('title' , '-release' )
@@ -937,20 +958,22 @@ def test_order_by_relation_pk(self):
937958 Apply order_by() with a field that returns a model without a default
938959 ordering (i.e. using the pk).
939960 """
940- # Order by publisher and ensure it takes.
961+ # Order by author and ensure it takes.
941962 with self .assertNumQueries (0 ):
942- qss = self .all .order_by ('publisher ' )
963+ qss = self .all .order_by ('author ' )
943964
944965 # Ensure that the test has any hope of passing.
945- self .assertLess (self .mad_magazine .pk , self .big_books .pk )
966+ self .assertLess (self .alice .pk , self .bob .pk )
946967
947968 # The first three should be from Mad Magazine, followed by three from
948969 # Big Books.
949970 # Note that the QuerySetSequence itself needs the publisher objects to
950971 # compare them, so they all get pulled in.
951972 with self .assertNumQueries (2 + 5 ):
952- for expected , element in zip ([self .mad_magazine .id ] * 3 + [self .big_books .id ] * 2 , qss ):
953- self .assertEqual (element .publisher .id , expected )
973+ self .assertEqual (
974+ [self .alice .id ] * 2 + [self .bob .id ] * 3 ,
975+ [b .author .id for b in qss ],
976+ )
954977
955978 def test_order_by_relation_with_ordering (self ):
956979 """
@@ -997,14 +1020,6 @@ def test_order_by_relation_field(self):
9971020 for expected , element in zip ([self .alice .id ] * 2 + [self .bob .id ] * 3 , qss ):
9981021 self .assertEqual (element .author .id , expected )
9991022
1000- def test_order_by_relation_no_existent_field (self ):
1001- """Apply order_by() with a field through a model relationship that doesn't exist."""
1002- with self .assertNumQueries (0 ):
1003- qss = self .all .order_by ('publisher__address' )
1004-
1005- with self .assertRaises (FieldError ):
1006- list (qss )
1007-
10081023 def test_order_by_queryset (self ):
10091024 """Ensure we can order by QuerySet and then other fields."""
10101025 # Order by title, but don't interleave each QuerySet.
@@ -1470,10 +1485,12 @@ def test_empty(self):
14701485class TestDelete (TestBase ):
14711486 def test_delete_all (self ):
14721487 """Ensure that delete() works properly."""
1473- with self .assertNumQueries (2 ):
1488+ # 4 queries is due to the models themselves and then the many-to-many
1489+ # relationships.
1490+ with self .assertNumQueries (4 ):
14741491 result = self .all .delete ()
1475- self .assertEqual (result [0 ], 5 )
1476- self .assertEqual (result [1 ], {'tests.Article' : 3 , 'tests.Book' : 2 })
1492+ self .assertEqual (result [0 ], 7 )
1493+ self .assertEqual (result [1 ], {'tests.Article' : 3 , 'tests.Book' : 2 , 'tests.Book_publishers' : 2 })
14771494
14781495 with self .assertNumQueries (2 ):
14791496 self .assertEqual (self .all .count (), 0 )
@@ -1483,10 +1500,7 @@ def test_delete_filter(self):
14831500 with self .assertNumQueries (2 ):
14841501 result = self .all .filter (author = self .alice ).delete ()
14851502 self .assertEqual (result [0 ], 2 )
1486- # Django 3.1 no longer returns 0 as the number of objects deleted.
14871503 expected = {'tests.Article' : 2 }
1488- if django .VERSION < (3 , 1 ):
1489- expected ['tests.Book' ] = 0
14901504 self .assertEqual (result [1 ], expected )
14911505
14921506 with self .assertNumQueries (2 ):
0 commit comments