parts/django/tests/regressiontests/queries/tests.py
changeset 307 c6bca38c1cbf
equal deleted inserted replaced
306:5ff1fc726848 307:c6bca38c1cbf
       
     1 import datetime
       
     2 import pickle
       
     3 import sys
       
     4 import unittest
       
     5 
       
     6 from django.conf import settings
       
     7 from django.core.exceptions import FieldError
       
     8 from django.db import DatabaseError, connection, connections, DEFAULT_DB_ALIAS
       
     9 from django.db.models import Count
       
    10 from django.db.models.query import Q, ITER_CHUNK_SIZE, EmptyQuerySet
       
    11 from django.test import TestCase
       
    12 from django.utils.datastructures import SortedDict
       
    13 
       
    14 from models import (Annotation, Article, Author, Celebrity, Child, Cover, Detail,
       
    15     DumbCategory, ExtraInfo, Fan, Item, LeafA, LoopX, LoopZ, ManagedModel,
       
    16     Member, NamedCategory, Note, Number, Plaything, PointerA, Ranking, Related,
       
    17     Report, ReservedName, Tag, TvChef, Valid, X)
       
    18 
       
    19 
       
    20 class BaseQuerysetTest(TestCase):
       
    21     def assertValueQuerysetEqual(self, qs, values):
       
    22         return self.assertQuerysetEqual(qs, values, transform=lambda x: x)
       
    23 
       
    24     def assertRaisesMessage(self, exc, msg, func, *args, **kwargs):
       
    25         try:
       
    26             func(*args, **kwargs)
       
    27         except Exception, e:
       
    28             self.assertEqual(msg, str(e))
       
    29             self.assertTrue(isinstance(e, exc), "Expected %s, got %s" % (exc, type(e)))
       
    30         else:
       
    31             if hasattr(exc, '__name__'):
       
    32                 excName = exc.__name__
       
    33             else:
       
    34                 excName = str(exc)
       
    35             raise AssertionError, "%s not raised" % excName
       
    36 
       
    37 
       
    38 class Queries1Tests(BaseQuerysetTest):
       
    39     def setUp(self):
       
    40         generic = NamedCategory.objects.create(name="Generic")
       
    41         self.t1 = Tag.objects.create(name='t1', category=generic)
       
    42         self.t2 = Tag.objects.create(name='t2', parent=self.t1, category=generic)
       
    43         self.t3 = Tag.objects.create(name='t3', parent=self.t1)
       
    44         t4 = Tag.objects.create(name='t4', parent=self.t3)
       
    45         self.t5 = Tag.objects.create(name='t5', parent=self.t3)
       
    46 
       
    47         self.n1 = Note.objects.create(note='n1', misc='foo', id=1)
       
    48         n2 = Note.objects.create(note='n2', misc='bar', id=2)
       
    49         self.n3 = Note.objects.create(note='n3', misc='foo', id=3)
       
    50 
       
    51         ann1 = Annotation.objects.create(name='a1', tag=self.t1)
       
    52         ann1.notes.add(self.n1)
       
    53         ann2 = Annotation.objects.create(name='a2', tag=t4)
       
    54         ann2.notes.add(n2, self.n3)
       
    55 
       
    56         # Create these out of order so that sorting by 'id' will be different to sorting
       
    57         # by 'info'. Helps detect some problems later.
       
    58         self.e2 = ExtraInfo.objects.create(info='e2', note=n2)
       
    59         e1 = ExtraInfo.objects.create(info='e1', note=self.n1)
       
    60 
       
    61         self.a1 = Author.objects.create(name='a1', num=1001, extra=e1)
       
    62         self.a2 = Author.objects.create(name='a2', num=2002, extra=e1)
       
    63         a3 = Author.objects.create(name='a3', num=3003, extra=self.e2)
       
    64         self.a4 = Author.objects.create(name='a4', num=4004, extra=self.e2)
       
    65 
       
    66         self.time1 = datetime.datetime(2007, 12, 19, 22, 25, 0)
       
    67         self.time2 = datetime.datetime(2007, 12, 19, 21, 0, 0)
       
    68         time3 = datetime.datetime(2007, 12, 20, 22, 25, 0)
       
    69         time4 = datetime.datetime(2007, 12, 20, 21, 0, 0)
       
    70         self.i1 = Item.objects.create(name='one', created=self.time1, modified=self.time1, creator=self.a1, note=self.n3)
       
    71         self.i1.tags = [self.t1, self.t2]
       
    72         self.i2 = Item.objects.create(name='two', created=self.time2, creator=self.a2, note=n2)
       
    73         self.i2.tags = [self.t1, self.t3]
       
    74         self.i3 = Item.objects.create(name='three', created=time3, creator=self.a2, note=self.n3)
       
    75         i4 = Item.objects.create(name='four', created=time4, creator=self.a4, note=self.n3)
       
    76         i4.tags = [t4]
       
    77 
       
    78         self.r1 = Report.objects.create(name='r1', creator=self.a1)
       
    79         Report.objects.create(name='r2', creator=a3)
       
    80         Report.objects.create(name='r3')
       
    81 
       
    82         # Ordering by 'rank' gives us rank2, rank1, rank3. Ordering by the Meta.ordering
       
    83         # will be rank3, rank2, rank1.
       
    84         self.rank1 = Ranking.objects.create(rank=2, author=self.a2)
       
    85 
       
    86         Cover.objects.create(title="first", item=i4)
       
    87         Cover.objects.create(title="second", item=self.i2)
       
    88 
       
    89     def test_ticket1050(self):
       
    90         self.assertQuerysetEqual(
       
    91             Item.objects.filter(tags__isnull=True),
       
    92             ['<Item: three>']
       
    93         )
       
    94         self.assertQuerysetEqual(
       
    95             Item.objects.filter(tags__id__isnull=True),
       
    96             ['<Item: three>']
       
    97         )
       
    98 
       
    99     def test_ticket1801(self):
       
   100         self.assertQuerysetEqual(
       
   101             Author.objects.filter(item=self.i2),
       
   102             ['<Author: a2>']
       
   103         )
       
   104         self.assertQuerysetEqual(
       
   105             Author.objects.filter(item=self.i3),
       
   106             ['<Author: a2>']
       
   107         )
       
   108         self.assertQuerysetEqual(
       
   109             Author.objects.filter(item=self.i2) & Author.objects.filter(item=self.i3),
       
   110             ['<Author: a2>']
       
   111         )
       
   112 
       
   113     def test_ticket2306(self):
       
   114         # Checking that no join types are "left outer" joins.
       
   115         query = Item.objects.filter(tags=self.t2).query
       
   116         self.assertTrue(query.LOUTER not in [x[2] for x in query.alias_map.values()])
       
   117 
       
   118         self.assertQuerysetEqual(
       
   119             Item.objects.filter(Q(tags=self.t1)).order_by('name'),
       
   120             ['<Item: one>', '<Item: two>']
       
   121         )
       
   122         self.assertQuerysetEqual(
       
   123             Item.objects.filter(Q(tags=self.t1)).filter(Q(tags=self.t2)),
       
   124             ['<Item: one>']
       
   125         )
       
   126         self.assertQuerysetEqual(
       
   127             Item.objects.filter(Q(tags=self.t1)).filter(Q(creator__name='fred')|Q(tags=self.t2)),
       
   128             ['<Item: one>']
       
   129         )
       
   130 
       
   131         # Each filter call is processed "at once" against a single table, so this is
       
   132         # different from the previous example as it tries to find tags that are two
       
   133         # things at once (rather than two tags).
       
   134         self.assertQuerysetEqual(
       
   135             Item.objects.filter(Q(tags=self.t1) & Q(tags=self.t2)),
       
   136             []
       
   137         )
       
   138         self.assertQuerysetEqual(
       
   139             Item.objects.filter(Q(tags=self.t1), Q(creator__name='fred')|Q(tags=self.t2)),
       
   140             []
       
   141         )
       
   142 
       
   143         qs = Author.objects.filter(ranking__rank=2, ranking__id=self.rank1.id)
       
   144         self.assertQuerysetEqual(list(qs), ['<Author: a2>'])
       
   145         self.assertEqual(2, qs.query.count_active_tables(), 2)
       
   146         qs = Author.objects.filter(ranking__rank=2).filter(ranking__id=self.rank1.id)
       
   147         self.assertEqual(qs.query.count_active_tables(), 3)
       
   148 
       
   149     def test_ticket4464(self):
       
   150         self.assertQuerysetEqual(
       
   151             Item.objects.filter(tags=self.t1).filter(tags=self.t2),
       
   152             ['<Item: one>']
       
   153         )
       
   154         self.assertQuerysetEqual(
       
   155             Item.objects.filter(tags__in=[self.t1, self.t2]).distinct().order_by('name'),
       
   156             ['<Item: one>', '<Item: two>']
       
   157         )
       
   158         self.assertQuerysetEqual(
       
   159             Item.objects.filter(tags__in=[self.t1, self.t2]).filter(tags=self.t3),
       
   160             ['<Item: two>']
       
   161         )
       
   162 
       
   163         # Make sure .distinct() works with slicing (this was broken in Oracle).
       
   164         self.assertQuerysetEqual(
       
   165             Item.objects.filter(tags__in=[self.t1, self.t2]).order_by('name')[:3],
       
   166             ['<Item: one>', '<Item: one>', '<Item: two>']
       
   167         )
       
   168         self.assertQuerysetEqual(
       
   169             Item.objects.filter(tags__in=[self.t1, self.t2]).distinct().order_by('name')[:3],
       
   170             ['<Item: one>', '<Item: two>']
       
   171         )
       
   172 
       
   173     def test_tickets_2080_3592(self):
       
   174         self.assertQuerysetEqual(
       
   175             Author.objects.filter(item__name='one') | Author.objects.filter(name='a3'),
       
   176             ['<Author: a1>', '<Author: a3>']
       
   177         )
       
   178         self.assertQuerysetEqual(
       
   179             Author.objects.filter(Q(item__name='one') | Q(name='a3')),
       
   180             ['<Author: a1>', '<Author: a3>']
       
   181         )
       
   182         self.assertQuerysetEqual(
       
   183             Author.objects.filter(Q(name='a3') | Q(item__name='one')),
       
   184             ['<Author: a1>', '<Author: a3>']
       
   185         )
       
   186         self.assertQuerysetEqual(
       
   187             Author.objects.filter(Q(item__name='three') | Q(report__name='r3')),
       
   188             ['<Author: a2>']
       
   189         )
       
   190 
       
   191     def test_ticket6074(self):
       
   192         # Merging two empty result sets shouldn't leave a queryset with no constraints
       
   193         # (which would match everything).
       
   194         self.assertQuerysetEqual(Author.objects.filter(Q(id__in=[])), [])
       
   195         self.assertQuerysetEqual(
       
   196             Author.objects.filter(Q(id__in=[])|Q(id__in=[])),
       
   197             []
       
   198         )
       
   199 
       
   200     def test_tickets_1878_2939(self):
       
   201         self.assertEqual(Item.objects.values('creator').distinct().count(), 3)
       
   202 
       
   203         # Create something with a duplicate 'name' so that we can test multi-column
       
   204         # cases (which require some tricky SQL transformations under the covers).
       
   205         xx = Item(name='four', created=self.time1, creator=self.a2, note=self.n1)
       
   206         xx.save()
       
   207         self.assertEqual(
       
   208             Item.objects.exclude(name='two').values('creator', 'name').distinct().count(),
       
   209             4
       
   210         )
       
   211         self.assertEqual(
       
   212             Item.objects.exclude(name='two').extra(select={'foo': '%s'}, select_params=(1,)).values('creator', 'name', 'foo').distinct().count(),
       
   213             4
       
   214         )
       
   215         self.assertEqual(
       
   216             Item.objects.exclude(name='two').extra(select={'foo': '%s'}, select_params=(1,)).values('creator', 'name').distinct().count(),
       
   217             4
       
   218         )
       
   219         xx.delete()
       
   220 
       
   221     def test_ticket7323(self):
       
   222         self.assertEqual(Item.objects.values('creator', 'name').count(), 4)
       
   223 
       
   224     def test_ticket2253(self):
       
   225         q1 = Item.objects.order_by('name')
       
   226         q2 = Item.objects.filter(id=self.i1.id)
       
   227         self.assertQuerysetEqual(
       
   228             q1,
       
   229             ['<Item: four>', '<Item: one>', '<Item: three>', '<Item: two>']
       
   230         )
       
   231         self.assertQuerysetEqual(q2, ['<Item: one>'])
       
   232         self.assertQuerysetEqual(
       
   233             (q1 | q2).order_by('name'),
       
   234             ['<Item: four>', '<Item: one>', '<Item: three>', '<Item: two>']
       
   235         )
       
   236         self.assertQuerysetEqual((q1 & q2).order_by('name'), ['<Item: one>'])
       
   237 
       
   238         # FIXME: This is difficult to fix and very much an edge case, so punt for now.
       
   239         # This is related to the order_by() tests, below, but the old bug exhibited
       
   240         # itself here (q2 was pulling too many tables into the combined query with the
       
   241         # new ordering, but only because we have evaluated q2 already).
       
   242         #
       
   243         #self.assertEqual(len((q1 & q2).order_by('name').query.tables), 1)
       
   244 
       
   245         q1 = Item.objects.filter(tags=self.t1)
       
   246         q2 = Item.objects.filter(note=self.n3, tags=self.t2)
       
   247         q3 = Item.objects.filter(creator=self.a4)
       
   248         self.assertQuerysetEqual(
       
   249             ((q1 & q2) | q3).order_by('name'),
       
   250             ['<Item: four>', '<Item: one>']
       
   251         )
       
   252 
       
   253     def test_tickets_4088_4306(self):
       
   254         self.assertQuerysetEqual(
       
   255             Report.objects.filter(creator=1001),
       
   256             ['<Report: r1>']
       
   257         )
       
   258         self.assertQuerysetEqual(
       
   259             Report.objects.filter(creator__num=1001),
       
   260             ['<Report: r1>']
       
   261         )
       
   262         self.assertQuerysetEqual(Report.objects.filter(creator__id=1001), [])
       
   263         self.assertQuerysetEqual(
       
   264             Report.objects.filter(creator__id=self.a1.id),
       
   265             ['<Report: r1>']
       
   266         )
       
   267         self.assertQuerysetEqual(
       
   268             Report.objects.filter(creator__name='a1'),
       
   269             ['<Report: r1>']
       
   270         )
       
   271 
       
   272     def test_ticket4510(self):
       
   273         self.assertQuerysetEqual(
       
   274             Author.objects.filter(report__name='r1'),
       
   275             ['<Author: a1>']
       
   276         )
       
   277 
       
   278     def test_ticket7378(self):
       
   279         self.assertQuerysetEqual(self.a1.report_set.all(), ['<Report: r1>'])
       
   280 
       
   281     def test_tickets_5324_6704(self):
       
   282         self.assertQuerysetEqual(
       
   283             Item.objects.filter(tags__name='t4'),
       
   284             ['<Item: four>']
       
   285         )
       
   286         self.assertQuerysetEqual(
       
   287             Item.objects.exclude(tags__name='t4').order_by('name').distinct(),
       
   288             ['<Item: one>', '<Item: three>', '<Item: two>']
       
   289         )
       
   290         self.assertQuerysetEqual(
       
   291             Item.objects.exclude(tags__name='t4').order_by('name').distinct().reverse(),
       
   292             ['<Item: two>', '<Item: three>', '<Item: one>']
       
   293         )
       
   294         self.assertQuerysetEqual(
       
   295             Author.objects.exclude(item__name='one').distinct().order_by('name'),
       
   296             ['<Author: a2>', '<Author: a3>', '<Author: a4>']
       
   297         )
       
   298 
       
   299         # Excluding across a m2m relation when there is more than one related
       
   300         # object associated was problematic.
       
   301         self.assertQuerysetEqual(
       
   302             Item.objects.exclude(tags__name='t1').order_by('name'),
       
   303             ['<Item: four>', '<Item: three>']
       
   304         )
       
   305         self.assertQuerysetEqual(
       
   306             Item.objects.exclude(tags__name='t1').exclude(tags__name='t4'),
       
   307             ['<Item: three>']
       
   308         )
       
   309 
       
   310         # Excluding from a relation that cannot be NULL should not use outer joins.
       
   311         query = Item.objects.exclude(creator__in=[self.a1, self.a2]).query
       
   312         self.assertTrue(query.LOUTER not in [x[2] for x in query.alias_map.values()])
       
   313 
       
   314         # Similarly, when one of the joins cannot possibly, ever, involve NULL
       
   315         # values (Author -> ExtraInfo, in the following), it should never be
       
   316         # promoted to a left outer join. So the following query should only
       
   317         # involve one "left outer" join (Author -> Item is 0-to-many).
       
   318         qs = Author.objects.filter(id=self.a1.id).filter(Q(extra__note=self.n1)|Q(item__note=self.n3))
       
   319         self.assertEqual(
       
   320             len([x[2] for x in qs.query.alias_map.values() if x[2] == query.LOUTER and qs.query.alias_refcount[x[1]]]),
       
   321             1
       
   322         )
       
   323 
       
   324         # The previous changes shouldn't affect nullable foreign key joins.
       
   325         self.assertQuerysetEqual(
       
   326             Tag.objects.filter(parent__isnull=True).order_by('name'),
       
   327             ['<Tag: t1>']
       
   328         )
       
   329         self.assertQuerysetEqual(
       
   330             Tag.objects.exclude(parent__isnull=True).order_by('name'),
       
   331             ['<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>']
       
   332         )
       
   333         self.assertQuerysetEqual(
       
   334             Tag.objects.exclude(Q(parent__name='t1') | Q(parent__isnull=True)).order_by('name'),
       
   335             ['<Tag: t4>', '<Tag: t5>']
       
   336         )
       
   337         self.assertQuerysetEqual(
       
   338             Tag.objects.exclude(Q(parent__isnull=True) | Q(parent__name='t1')).order_by('name'),
       
   339             ['<Tag: t4>', '<Tag: t5>']
       
   340         )
       
   341         self.assertQuerysetEqual(
       
   342             Tag.objects.exclude(Q(parent__parent__isnull=True)).order_by('name'),
       
   343             ['<Tag: t4>', '<Tag: t5>']
       
   344         )
       
   345         self.assertQuerysetEqual(
       
   346             Tag.objects.filter(~Q(parent__parent__isnull=True)).order_by('name'),
       
   347             ['<Tag: t4>', '<Tag: t5>']
       
   348         )
       
   349 
       
   350     def test_ticket2091(self):
       
   351         t = Tag.objects.get(name='t4')
       
   352         self.assertQuerysetEqual(
       
   353             Item.objects.filter(tags__in=[t]),
       
   354             ['<Item: four>']
       
   355         )
       
   356 
       
   357     def test_heterogeneous_qs_combination(self):
       
   358         # Combining querysets built on different models should behave in a well-defined
       
   359         # fashion. We raise an error.
       
   360         self.assertRaisesMessage(
       
   361             AssertionError,
       
   362             'Cannot combine queries on two different base models.',
       
   363             lambda: Author.objects.all() & Tag.objects.all()
       
   364         )
       
   365         self.assertRaisesMessage(
       
   366             AssertionError,
       
   367             'Cannot combine queries on two different base models.',
       
   368             lambda: Author.objects.all() | Tag.objects.all()
       
   369         )
       
   370 
       
   371     def test_ticket3141(self):
       
   372         self.assertEqual(Author.objects.extra(select={'foo': '1'}).count(), 4)
       
   373         self.assertEqual(
       
   374             Author.objects.extra(select={'foo': '%s'}, select_params=(1,)).count(),
       
   375             4
       
   376         )
       
   377 
       
   378     def test_ticket2400(self):
       
   379         self.assertQuerysetEqual(
       
   380             Author.objects.filter(item__isnull=True),
       
   381             ['<Author: a3>']
       
   382         )
       
   383         self.assertQuerysetEqual(
       
   384             Tag.objects.filter(item__isnull=True),
       
   385             ['<Tag: t5>']
       
   386         )
       
   387 
       
   388     def test_ticket2496(self):
       
   389         self.assertQuerysetEqual(
       
   390             Item.objects.extra(tables=['queries_author']).select_related().order_by('name')[:1],
       
   391             ['<Item: four>']
       
   392         )
       
   393 
       
   394     def test_tickets_2076_7256(self):
       
   395         # Ordering on related tables should be possible, even if the table is
       
   396         # not otherwise involved.
       
   397         self.assertQuerysetEqual(
       
   398             Item.objects.order_by('note__note', 'name'),
       
   399             ['<Item: two>', '<Item: four>', '<Item: one>', '<Item: three>']
       
   400         )
       
   401 
       
   402         # Ordering on a related field should use the remote model's default
       
   403         # ordering as a final step.
       
   404         self.assertQuerysetEqual(
       
   405             Author.objects.order_by('extra', '-name'),
       
   406             ['<Author: a2>', '<Author: a1>', '<Author: a4>', '<Author: a3>']
       
   407         )
       
   408 
       
   409         # Using remote model default ordering can span multiple models (in this
       
   410         # case, Cover is ordered by Item's default, which uses Note's default).
       
   411         self.assertQuerysetEqual(
       
   412             Cover.objects.all(),
       
   413             ['<Cover: first>', '<Cover: second>']
       
   414         )
       
   415 
       
   416         # If the remote model does not have a default ordering, we order by its 'id'
       
   417         # field.
       
   418         self.assertQuerysetEqual(
       
   419             Item.objects.order_by('creator', 'name'),
       
   420             ['<Item: one>', '<Item: three>', '<Item: two>', '<Item: four>']
       
   421         )
       
   422 
       
   423         # Ordering by a many-valued attribute (e.g. a many-to-many or reverse
       
   424         # ForeignKey) is legal, but the results might not make sense. That
       
   425         # isn't Django's problem. Garbage in, garbage out.
       
   426         self.assertQuerysetEqual(
       
   427             Item.objects.filter(tags__isnull=False).order_by('tags', 'id'),
       
   428             ['<Item: one>', '<Item: two>', '<Item: one>', '<Item: two>', '<Item: four>']
       
   429         )
       
   430 
       
   431         # If we replace the default ordering, Django adjusts the required
       
   432         # tables automatically. Item normally requires a join with Note to do
       
   433         # the default ordering, but that isn't needed here.
       
   434         qs = Item.objects.order_by('name')
       
   435         self.assertQuerysetEqual(
       
   436             qs,
       
   437             ['<Item: four>', '<Item: one>', '<Item: three>', '<Item: two>']
       
   438         )
       
   439         self.assertEqual(len(qs.query.tables), 1)
       
   440 
       
   441     def test_tickets_2874_3002(self):
       
   442         qs = Item.objects.select_related().order_by('note__note', 'name')
       
   443         self.assertQuerysetEqual(
       
   444             qs,
       
   445             ['<Item: two>', '<Item: four>', '<Item: one>', '<Item: three>']
       
   446         )
       
   447 
       
   448         # This is also a good select_related() test because there are multiple
       
   449         # Note entries in the SQL. The two Note items should be different.
       
   450         self.assertTrue(repr(qs[0].note), '<Note: n2>')
       
   451         self.assertEqual(repr(qs[0].creator.extra.note), '<Note: n1>')
       
   452 
       
   453     def test_ticket3037(self):
       
   454         self.assertQuerysetEqual(
       
   455             Item.objects.filter(Q(creator__name='a3', name='two')|Q(creator__name='a4', name='four')),
       
   456             ['<Item: four>']
       
   457         )
       
   458 
       
   459     def test_tickets_5321_7070(self):
       
   460         # Ordering columns must be included in the output columns. Note that
       
   461         # this means results that might otherwise be distinct are not (if there
       
   462         # are multiple values in the ordering cols), as in this example. This
       
   463         # isn't a bug; it's a warning to be careful with the selection of
       
   464         # ordering columns.
       
   465         self.assertValueQuerysetEqual(
       
   466             Note.objects.values('misc').distinct().order_by('note', '-misc'),
       
   467             [{'misc': u'foo'}, {'misc': u'bar'}, {'misc': u'foo'}]
       
   468         )
       
   469 
       
   470     def test_ticket4358(self):
       
   471         # If you don't pass any fields to values(), relation fields are
       
   472         # returned as "foo_id" keys, not "foo". For consistency, you should be
       
   473         # able to pass "foo_id" in the fields list and have it work, too. We
       
   474         # actually allow both "foo" and "foo_id".
       
   475 
       
   476         # The *_id version is returned by default.
       
   477         self.assertTrue('note_id' in ExtraInfo.objects.values()[0])
       
   478 
       
   479         # You can also pass it in explicitly.
       
   480         self.assertValueQuerysetEqual(
       
   481             ExtraInfo.objects.values('note_id'),
       
   482             [{'note_id': 1}, {'note_id': 2}]
       
   483         )
       
   484 
       
   485         # ...or use the field name.
       
   486         self.assertValueQuerysetEqual(
       
   487             ExtraInfo.objects.values('note'),
       
   488             [{'note': 1}, {'note': 2}]
       
   489         )
       
   490 
       
   491     def test_ticket2902(self):
       
   492         # Parameters can be given to extra_select, *if* you use a SortedDict.
       
   493 
       
   494         # (First we need to know which order the keys fall in "naturally" on
       
   495         # your system, so we can put things in the wrong way around from
       
   496         # normal. A normal dict would thus fail.)
       
   497         s = [('a', '%s'), ('b', '%s')]
       
   498         params = ['one', 'two']
       
   499         if {'a': 1, 'b': 2}.keys() == ['a', 'b']:
       
   500             s.reverse()
       
   501             params.reverse()
       
   502 
       
   503         # This slightly odd comparison works around the fact that PostgreSQL will
       
   504         # return 'one' and 'two' as strings, not Unicode objects. It's a side-effect of
       
   505         # using constants here and not a real concern.
       
   506         d = Item.objects.extra(select=SortedDict(s), select_params=params).values('a', 'b')[0]
       
   507         self.assertEqual(d, {'a': u'one', 'b': u'two'})
       
   508 
       
   509         # Order by the number of tags attached to an item.
       
   510         l = Item.objects.extra(select={'count': 'select count(*) from queries_item_tags where queries_item_tags.item_id = queries_item.id'}).order_by('-count')
       
   511         self.assertEqual([o.count for o in l], [2, 2, 1, 0])
       
   512 
       
   513     def test_ticket6154(self):
       
   514         # Multiple filter statements are joined using "AND" all the time.
       
   515 
       
   516         self.assertQuerysetEqual(
       
   517             Author.objects.filter(id=self.a1.id).filter(Q(extra__note=self.n1)|Q(item__note=self.n3)),
       
   518             ['<Author: a1>']
       
   519         )
       
   520         self.assertQuerysetEqual(
       
   521                 Author.objects.filter(Q(extra__note=self.n1)|Q(item__note=self.n3)).filter(id=self.a1.id),
       
   522             ['<Author: a1>']
       
   523         )
       
   524 
       
   525     def test_ticket6981(self):
       
   526         self.assertQuerysetEqual(
       
   527             Tag.objects.select_related('parent').order_by('name'),
       
   528             ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>']
       
   529         )
       
   530 
       
   531     def test_ticket9926(self):
       
   532         self.assertQuerysetEqual(
       
   533             Tag.objects.select_related("parent", "category").order_by('name'),
       
   534             ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>']
       
   535         )
       
   536         self.assertQuerysetEqual(
       
   537             Tag.objects.select_related('parent', "parent__category").order_by('name'),
       
   538             ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>']
       
   539         )
       
   540 
       
   541     def test_tickets_6180_6203(self):
       
   542         # Dates with limits and/or counts
       
   543         self.assertEqual(Item.objects.count(), 4)
       
   544         self.assertEqual(Item.objects.dates('created', 'month').count(), 1)
       
   545         self.assertEqual(Item.objects.dates('created', 'day').count(), 2)
       
   546         self.assertEqual(len(Item.objects.dates('created', 'day')), 2)
       
   547         self.assertEqual(Item.objects.dates('created', 'day')[0], datetime.datetime(2007, 12, 19, 0, 0))
       
   548 
       
   549     def test_tickets_7087_12242(self):
       
   550         # Dates with extra select columns
       
   551         self.assertQuerysetEqual(
       
   552             Item.objects.dates('created', 'day').extra(select={'a': 1}),
       
   553             ['datetime.datetime(2007, 12, 19, 0, 0)', 'datetime.datetime(2007, 12, 20, 0, 0)']
       
   554         )
       
   555         self.assertQuerysetEqual(
       
   556             Item.objects.extra(select={'a': 1}).dates('created', 'day'),
       
   557             ['datetime.datetime(2007, 12, 19, 0, 0)', 'datetime.datetime(2007, 12, 20, 0, 0)']
       
   558         )
       
   559 
       
   560         name="one"
       
   561         self.assertQuerysetEqual(
       
   562             Item.objects.dates('created', 'day').extra(where=['name=%s'], params=[name]),
       
   563             ['datetime.datetime(2007, 12, 19, 0, 0)']
       
   564         )
       
   565 
       
   566         self.assertQuerysetEqual(
       
   567             Item.objects.extra(where=['name=%s'], params=[name]).dates('created', 'day'),
       
   568             ['datetime.datetime(2007, 12, 19, 0, 0)']
       
   569         )
       
   570 
       
   571     def test_ticket7155(self):
       
   572         # Nullable dates
       
   573         self.assertQuerysetEqual(
       
   574             Item.objects.dates('modified', 'day'),
       
   575             ['datetime.datetime(2007, 12, 19, 0, 0)']
       
   576         )
       
   577 
       
   578     def test_ticket7098(self):
       
   579         # Make sure semi-deprecated ordering by related models syntax still
       
   580         # works.
       
   581         self.assertValueQuerysetEqual(
       
   582             Item.objects.values('note__note').order_by('queries_note.note', 'id'),
       
   583             [{'note__note': u'n2'}, {'note__note': u'n3'}, {'note__note': u'n3'}, {'note__note': u'n3'}]
       
   584         )
       
   585 
       
   586     def test_ticket7096(self):
       
   587         # Make sure exclude() with multiple conditions continues to work.
       
   588         self.assertQuerysetEqual(
       
   589             Tag.objects.filter(parent=self.t1, name='t3').order_by('name'),
       
   590             ['<Tag: t3>']
       
   591         )
       
   592         self.assertQuerysetEqual(
       
   593             Tag.objects.exclude(parent=self.t1, name='t3').order_by('name'),
       
   594             ['<Tag: t1>', '<Tag: t2>', '<Tag: t4>', '<Tag: t5>']
       
   595         )
       
   596         self.assertQuerysetEqual(
       
   597             Item.objects.exclude(tags__name='t1', name='one').order_by('name').distinct(),
       
   598             ['<Item: four>', '<Item: three>', '<Item: two>']
       
   599         )
       
   600         self.assertQuerysetEqual(
       
   601             Item.objects.filter(name__in=['three', 'four']).exclude(tags__name='t1').order_by('name'),
       
   602             ['<Item: four>', '<Item: three>']
       
   603         )
       
   604 
       
   605         # More twisted cases, involving nested negations.
       
   606         self.assertQuerysetEqual(
       
   607             Item.objects.exclude(~Q(tags__name='t1', name='one')),
       
   608             ['<Item: one>']
       
   609         )
       
   610         self.assertQuerysetEqual(
       
   611             Item.objects.filter(~Q(tags__name='t1', name='one'), name='two'),
       
   612             ['<Item: two>']
       
   613         )
       
   614         self.assertQuerysetEqual(
       
   615             Item.objects.exclude(~Q(tags__name='t1', name='one'), name='two'),
       
   616             ['<Item: four>', '<Item: one>', '<Item: three>']
       
   617         )
       
   618 
       
   619     def test_tickets_7204_7506(self):
       
   620         # Make sure querysets with related fields can be pickled. If this
       
   621         # doesn't crash, it's a Good Thing.
       
   622         pickle.dumps(Item.objects.all())
       
   623 
       
   624     def test_ticket7813(self):
       
   625         # We should also be able to pickle things that use select_related().
       
   626         # The only tricky thing here is to ensure that we do the related
       
   627         # selections properly after unpickling.
       
   628         qs = Item.objects.select_related()
       
   629         query = qs.query.get_compiler(qs.db).as_sql()[0]
       
   630         query2 = pickle.loads(pickle.dumps(qs.query))
       
   631         self.assertEqual(
       
   632             query2.get_compiler(qs.db).as_sql()[0],
       
   633             query
       
   634         )
       
   635 
       
   636     def test_deferred_load_qs_pickling(self):
       
   637         # Check pickling of deferred-loading querysets
       
   638         qs = Item.objects.defer('name', 'creator')
       
   639         q2 = pickle.loads(pickle.dumps(qs))
       
   640         self.assertEqual(list(qs), list(q2))
       
   641         q3 = pickle.loads(pickle.dumps(qs, pickle.HIGHEST_PROTOCOL))
       
   642         self.assertEqual(list(qs), list(q3))
       
   643 
       
   644     def test_ticket7277(self):
       
   645         self.assertQuerysetEqual(
       
   646             self.n1.annotation_set.filter(Q(tag=self.t5) | Q(tag__children=self.t5) | Q(tag__children__children=self.t5)),
       
   647             ['<Annotation: a1>']
       
   648         )
       
   649 
       
   650     def test_tickets_7448_7707(self):
       
   651         # Complex objects should be converted to strings before being used in
       
   652         # lookups.
       
   653         self.assertQuerysetEqual(
       
   654             Item.objects.filter(created__in=[self.time1, self.time2]),
       
   655             ['<Item: one>', '<Item: two>']
       
   656         )
       
   657 
       
   658     def test_ticket7235(self):
       
   659         # An EmptyQuerySet should not raise exceptions if it is filtered.
       
   660         q = EmptyQuerySet()
       
   661         self.assertQuerysetEqual(q.all(), [])
       
   662         self.assertQuerysetEqual(q.filter(x=10), [])
       
   663         self.assertQuerysetEqual(q.exclude(y=3), [])
       
   664         self.assertQuerysetEqual(q.complex_filter({'pk': 1}), [])
       
   665         self.assertQuerysetEqual(q.select_related('spam', 'eggs'), [])
       
   666         self.assertQuerysetEqual(q.annotate(Count('eggs')), [])
       
   667         self.assertQuerysetEqual(q.order_by('-pub_date', 'headline'), [])
       
   668         self.assertQuerysetEqual(q.distinct(), [])
       
   669         self.assertQuerysetEqual(
       
   670             q.extra(select={'is_recent': "pub_date > '2006-01-01'"}),
       
   671             []
       
   672         )
       
   673         q.query.low_mark = 1
       
   674         self.assertRaisesMessage(
       
   675             AssertionError,
       
   676             'Cannot change a query once a slice has been taken',
       
   677             q.extra, select={'is_recent': "pub_date > '2006-01-01'"}
       
   678         )
       
   679         self.assertQuerysetEqual(q.reverse(), [])
       
   680         self.assertQuerysetEqual(q.defer('spam', 'eggs'), [])
       
   681         self.assertQuerysetEqual(q.only('spam', 'eggs'), [])
       
   682 
       
   683     def test_ticket7791(self):
       
   684         # There were "issues" when ordering and distinct-ing on fields related
       
   685         # via ForeignKeys.
       
   686         self.assertEqual(
       
   687             len(Note.objects.order_by('extrainfo__info').distinct()),
       
   688             3
       
   689         )
       
   690 
       
   691         # Pickling of DateQuerySets used to fail
       
   692         qs = Item.objects.dates('created', 'month')
       
   693         _ = pickle.loads(pickle.dumps(qs))
       
   694 
       
   695     def test_ticket9997(self):
       
   696         # If a ValuesList or Values queryset is passed as an inner query, we
       
   697         # make sure it's only requesting a single value and use that as the
       
   698         # thing to select.
       
   699         self.assertQuerysetEqual(
       
   700             Tag.objects.filter(name__in=Tag.objects.filter(parent=self.t1).values('name')),
       
   701             ['<Tag: t2>', '<Tag: t3>']
       
   702         )
       
   703 
       
   704         # Multi-valued values() and values_list() querysets should raise errors.
       
   705         self.assertRaisesMessage(
       
   706             TypeError,
       
   707             'Cannot use a multi-field ValuesQuerySet as a filter value.',
       
   708             lambda: Tag.objects.filter(name__in=Tag.objects.filter(parent=self.t1).values('name', 'id'))
       
   709         )
       
   710         self.assertRaisesMessage(
       
   711             TypeError,
       
   712             'Cannot use a multi-field ValuesListQuerySet as a filter value.',
       
   713             lambda: Tag.objects.filter(name__in=Tag.objects.filter(parent=self.t1).values_list('name', 'id'))
       
   714         )
       
   715 
       
   716     def test_ticket9985(self):
       
   717         # qs.values_list(...).values(...) combinations should work.
       
   718         self.assertValueQuerysetEqual(
       
   719             Note.objects.values_list("note", flat=True).values("id").order_by("id"),
       
   720             [{'id': 1}, {'id': 2}, {'id': 3}]
       
   721         )
       
   722         self.assertQuerysetEqual(
       
   723             Annotation.objects.filter(notes__in=Note.objects.filter(note="n1").values_list('note').values('id')),
       
   724             ['<Annotation: a1>']
       
   725         )
       
   726 
       
   727     def test_ticket10205(self):
       
   728         # When bailing out early because of an empty "__in" filter, we need
       
   729         # to set things up correctly internally so that subqueries can continue properly.
       
   730         self.assertEqual(Tag.objects.filter(name__in=()).update(name="foo"), 0)
       
   731 
       
   732     def test_ticket10432(self):
       
   733         # Testing an empty "__in" filter with a generator as the value.
       
   734         def f():
       
   735             return iter([])
       
   736         n_obj = Note.objects.all()[0]
       
   737         def g():
       
   738             for i in [n_obj.pk]:
       
   739                 yield i
       
   740         self.assertQuerysetEqual(Note.objects.filter(pk__in=f()), [])
       
   741         self.assertEqual(list(Note.objects.filter(pk__in=g())), [n_obj])
       
   742 
       
   743     def test_ticket10742(self):
       
   744         # Queries used in an __in clause don't execute subqueries
       
   745 
       
   746         subq = Author.objects.filter(num__lt=3000)
       
   747         qs = Author.objects.filter(pk__in=subq)
       
   748         self.assertQuerysetEqual(qs, ['<Author: a1>', '<Author: a2>'])
       
   749 
       
   750         # The subquery result cache should not be populated
       
   751         self.assertTrue(subq._result_cache is None)
       
   752 
       
   753         subq = Author.objects.filter(num__lt=3000)
       
   754         qs = Author.objects.exclude(pk__in=subq)
       
   755         self.assertQuerysetEqual(qs, ['<Author: a3>', '<Author: a4>'])
       
   756 
       
   757         # The subquery result cache should not be populated
       
   758         self.assertTrue(subq._result_cache is None)
       
   759 
       
   760         subq = Author.objects.filter(num__lt=3000)
       
   761         self.assertQuerysetEqual(
       
   762             Author.objects.filter(Q(pk__in=subq) & Q(name='a1')),
       
   763             ['<Author: a1>']
       
   764         )
       
   765 
       
   766         # The subquery result cache should not be populated
       
   767         self.assertTrue(subq._result_cache is None)
       
   768 
       
   769     def test_ticket7076(self):
       
   770         # Excluding shouldn't eliminate NULL entries.
       
   771         self.assertQuerysetEqual(
       
   772             Item.objects.exclude(modified=self.time1).order_by('name'),
       
   773             ['<Item: four>', '<Item: three>', '<Item: two>']
       
   774         )
       
   775         self.assertQuerysetEqual(
       
   776             Tag.objects.exclude(parent__name=self.t1.name),
       
   777             ['<Tag: t1>', '<Tag: t4>', '<Tag: t5>']
       
   778         )
       
   779 
       
   780     def test_ticket7181(self):
       
   781         # Ordering by related tables should accomodate nullable fields (this
       
   782         # test is a little tricky, since NULL ordering is database dependent.
       
   783         # Instead, we just count the number of results).
       
   784         self.assertEqual(len(Tag.objects.order_by('parent__name')), 5)
       
   785 
       
   786         # Empty querysets can be merged with others.
       
   787         self.assertQuerysetEqual(
       
   788             Note.objects.none() | Note.objects.all(),
       
   789             ['<Note: n1>', '<Note: n2>', '<Note: n3>']
       
   790         )
       
   791         self.assertQuerysetEqual(
       
   792             Note.objects.all() | Note.objects.none(),
       
   793             ['<Note: n1>', '<Note: n2>', '<Note: n3>']
       
   794         )
       
   795         self.assertQuerysetEqual(Note.objects.none() & Note.objects.all(), [])
       
   796         self.assertQuerysetEqual(Note.objects.all() & Note.objects.none(), [])
       
   797 
       
   798     def test_ticket9411(self):
       
   799         # Make sure bump_prefix() (an internal Query method) doesn't (re-)break. It's
       
   800         # sufficient that this query runs without error.
       
   801         qs = Tag.objects.values_list('id', flat=True).order_by('id')
       
   802         qs.query.bump_prefix()
       
   803         first = qs[0]
       
   804         self.assertEqual(list(qs), range(first, first+5))
       
   805 
       
   806     def test_ticket8439(self):
       
   807         # Complex combinations of conjunctions, disjunctions and nullable
       
   808         # relations.
       
   809         self.assertQuerysetEqual(
       
   810             Author.objects.filter(Q(item__note__extrainfo=self.e2)|Q(report=self.r1, name='xyz')),
       
   811             ['<Author: a2>']
       
   812         )
       
   813         self.assertQuerysetEqual(
       
   814             Author.objects.filter(Q(report=self.r1, name='xyz')|Q(item__note__extrainfo=self.e2)),
       
   815             ['<Author: a2>']
       
   816         )
       
   817         self.assertQuerysetEqual(
       
   818             Annotation.objects.filter(Q(tag__parent=self.t1)|Q(notes__note='n1', name='a1')),
       
   819             ['<Annotation: a1>']
       
   820         )
       
   821         xx = ExtraInfo.objects.create(info='xx', note=self.n3)
       
   822         self.assertQuerysetEqual(
       
   823             Note.objects.filter(Q(extrainfo__author=self.a1)|Q(extrainfo=xx)),
       
   824             ['<Note: n1>', '<Note: n3>']
       
   825         )
       
   826         xx.delete()
       
   827         q = Note.objects.filter(Q(extrainfo__author=self.a1)|Q(extrainfo=xx)).query
       
   828         self.assertEqual(
       
   829             len([x[2] for x in q.alias_map.values() if x[2] == q.LOUTER and q.alias_refcount[x[1]]]),
       
   830             1
       
   831         )
       
   832 
       
   833 
       
   834 class Queries2Tests(TestCase):
       
   835     def setUp(self):
       
   836         Number.objects.create(num=4)
       
   837         Number.objects.create(num=8)
       
   838         Number.objects.create(num=12)
       
   839 
       
   840     def test_ticket4289(self):
       
   841         # A slight variation on the restricting the filtering choices by the
       
   842         # lookup constraints.
       
   843         self.assertQuerysetEqual(Number.objects.filter(num__lt=4), [])
       
   844         self.assertQuerysetEqual(Number.objects.filter(num__gt=8, num__lt=12), [])
       
   845         self.assertQuerysetEqual(
       
   846             Number.objects.filter(num__gt=8, num__lt=13),
       
   847             ['<Number: 12>']
       
   848         )
       
   849         self.assertQuerysetEqual(
       
   850             Number.objects.filter(Q(num__lt=4) | Q(num__gt=8, num__lt=12)),
       
   851             []
       
   852         )
       
   853         self.assertQuerysetEqual(
       
   854             Number.objects.filter(Q(num__gt=8, num__lt=12) | Q(num__lt=4)),
       
   855             []
       
   856         )
       
   857         self.assertQuerysetEqual(
       
   858             Number.objects.filter(Q(num__gt=8) & Q(num__lt=12) | Q(num__lt=4)),
       
   859             []
       
   860         )
       
   861         self.assertQuerysetEqual(
       
   862             Number.objects.filter(Q(num__gt=7) & Q(num__lt=12) | Q(num__lt=4)),
       
   863             ['<Number: 8>']
       
   864         )
       
   865 
       
   866     def test_ticket12239(self):
       
   867         # Float was being rounded to integer on gte queries on integer field.  Tests
       
   868         # show that gt, lt, gte, and lte work as desired.  Note that the fix changes
       
   869         # get_prep_lookup for gte and lt queries only.
       
   870         self.assertQuerysetEqual(
       
   871             Number.objects.filter(num__gt=11.9),
       
   872             ['<Number: 12>']
       
   873         )
       
   874         self.assertQuerysetEqual(Number.objects.filter(num__gt=12), [])
       
   875         self.assertQuerysetEqual(Number.objects.filter(num__gt=12.0), [])
       
   876         self.assertQuerysetEqual(Number.objects.filter(num__gt=12.1), [])
       
   877         self.assertQuerysetEqual(
       
   878             Number.objects.filter(num__lt=12),
       
   879             ['<Number: 4>', '<Number: 8>']
       
   880         )
       
   881         self.assertQuerysetEqual(
       
   882             Number.objects.filter(num__lt=12.0),
       
   883             ['<Number: 4>', '<Number: 8>']
       
   884         )
       
   885         self.assertQuerysetEqual(
       
   886             Number.objects.filter(num__lt=12.1),
       
   887             ['<Number: 4>', '<Number: 8>', '<Number: 12>']
       
   888         )
       
   889         self.assertQuerysetEqual(
       
   890             Number.objects.filter(num__gte=11.9),
       
   891             ['<Number: 12>']
       
   892         )
       
   893         self.assertQuerysetEqual(
       
   894             Number.objects.filter(num__gte=12),
       
   895             ['<Number: 12>']
       
   896         )
       
   897         self.assertQuerysetEqual(
       
   898             Number.objects.filter(num__gte=12.0),
       
   899             ['<Number: 12>']
       
   900         )
       
   901         self.assertQuerysetEqual(Number.objects.filter(num__gte=12.1), [])
       
   902         self.assertQuerysetEqual(Number.objects.filter(num__gte=12.9), [])
       
   903         self.assertQuerysetEqual(
       
   904             Number.objects.filter(num__lte=11.9),
       
   905             ['<Number: 4>', '<Number: 8>']
       
   906         )
       
   907         self.assertQuerysetEqual(
       
   908             Number.objects.filter(num__lte=12),
       
   909             ['<Number: 4>', '<Number: 8>', '<Number: 12>']
       
   910         )
       
   911         self.assertQuerysetEqual(
       
   912             Number.objects.filter(num__lte=12.0),
       
   913             ['<Number: 4>', '<Number: 8>', '<Number: 12>']
       
   914         )
       
   915         self.assertQuerysetEqual(
       
   916             Number.objects.filter(num__lte=12.1),
       
   917             ['<Number: 4>', '<Number: 8>', '<Number: 12>']
       
   918         )
       
   919         self.assertQuerysetEqual(
       
   920             Number.objects.filter(num__lte=12.9),
       
   921             ['<Number: 4>', '<Number: 8>', '<Number: 12>']
       
   922         )
       
   923 
       
   924     def test_ticket7411(self):
       
   925         # Saving to db must work even with partially read result set in another
       
   926         # cursor.
       
   927         for num in range(2 * ITER_CHUNK_SIZE + 1):
       
   928             _ = Number.objects.create(num=num)
       
   929 
       
   930         for i, obj in enumerate(Number.objects.all()):
       
   931             obj.save()
       
   932             if i > 10: break
       
   933 
       
   934     def test_ticket7759(self):
       
   935         # Count should work with a partially read result set.
       
   936         count = Number.objects.count()
       
   937         qs = Number.objects.all()
       
   938         def run():
       
   939             for obj in qs:
       
   940                 return qs.count() == count
       
   941         self.assertTrue(run())
       
   942 
       
   943 
       
   944 class Queries3Tests(BaseQuerysetTest):
       
   945     def test_ticket7107(self):
       
   946         # This shouldn't create an infinite loop.
       
   947         self.assertQuerysetEqual(Valid.objects.all(), [])
       
   948 
       
   949     def test_ticket8683(self):
       
   950         # Raise proper error when a DateQuerySet gets passed a wrong type of
       
   951         # field
       
   952         self.assertRaisesMessage(
       
   953             AssertionError,
       
   954             "'name' isn't a DateField.",
       
   955             Item.objects.dates, 'name', 'month'
       
   956         )
       
   957 
       
   958 class Queries4Tests(BaseQuerysetTest):
       
   959     def setUp(self):
       
   960         generic = NamedCategory.objects.create(name="Generic")
       
   961         self.t1 = Tag.objects.create(name='t1', category=generic)
       
   962 
       
   963         n1 = Note.objects.create(note='n1', misc='foo', id=1)
       
   964         n2 = Note.objects.create(note='n2', misc='bar', id=2)
       
   965 
       
   966         e1 = ExtraInfo.objects.create(info='e1', note=n1)
       
   967         e2 = ExtraInfo.objects.create(info='e2', note=n2)
       
   968 
       
   969         a1 = Author.objects.create(name='a1', num=1001, extra=e1)
       
   970         a3 = Author.objects.create(name='a3', num=3003, extra=e2)
       
   971 
       
   972         Report.objects.create(name='r1', creator=a1)
       
   973         Report.objects.create(name='r2', creator=a3)
       
   974         Report.objects.create(name='r3')
       
   975 
       
   976     def test_ticket7095(self):
       
   977         # Updates that are filtered on the model being updated are somewhat
       
   978         # tricky in MySQL. This exercises that case.
       
   979         ManagedModel.objects.create(data='mm1', tag=self.t1, public=True)
       
   980         self.assertEqual(ManagedModel.objects.update(data='mm'), 1)
       
   981 
       
   982         # A values() or values_list() query across joined models must use outer
       
   983         # joins appropriately.
       
   984         # Note: In Oracle, we expect a null CharField to return u'' instead of
       
   985         # None.
       
   986         if connection.features.interprets_empty_strings_as_nulls:
       
   987             expected_null_charfield_repr = u''
       
   988         else:
       
   989             expected_null_charfield_repr = None
       
   990         self.assertValueQuerysetEqual(
       
   991             Report.objects.values_list("creator__extra__info", flat=True).order_by("name"),
       
   992             [u'e1', u'e2', expected_null_charfield_repr],
       
   993         )
       
   994 
       
   995         # Similarly for select_related(), joins beyond an initial nullable join
       
   996         # must use outer joins so that all results are included.
       
   997         self.assertQuerysetEqual(
       
   998             Report.objects.select_related("creator", "creator__extra").order_by("name"),
       
   999             ['<Report: r1>', '<Report: r2>', '<Report: r3>']
       
  1000         )
       
  1001 
       
  1002         # When there are multiple paths to a table from another table, we have
       
  1003         # to be careful not to accidentally reuse an inappropriate join when
       
  1004         # using select_related(). We used to return the parent's Detail record
       
  1005         # here by mistake.
       
  1006 
       
  1007         d1 = Detail.objects.create(data="d1")
       
  1008         d2 = Detail.objects.create(data="d2")
       
  1009         m1 = Member.objects.create(name="m1", details=d1)
       
  1010         m2 = Member.objects.create(name="m2", details=d2)
       
  1011         Child.objects.create(person=m2, parent=m1)
       
  1012         obj = m1.children.select_related("person__details")[0]
       
  1013         self.assertEqual(obj.person.details.data, u'd2')
       
  1014 
       
  1015     def test_order_by_resetting(self):
       
  1016         # Calling order_by() with no parameters removes any existing ordering on the
       
  1017         # model. But it should still be possible to add new ordering after that.
       
  1018         qs = Author.objects.order_by().order_by('name')
       
  1019         self.assertTrue('ORDER BY' in qs.query.get_compiler(qs.db).as_sql()[0])
       
  1020 
       
  1021     def test_ticket10181(self):
       
  1022         # Avoid raising an EmptyResultSet if an inner query is probably
       
  1023         # empty (and hence, not executed).
       
  1024         self.assertQuerysetEqual(
       
  1025             Tag.objects.filter(id__in=Tag.objects.filter(id__in=[])),
       
  1026             []
       
  1027         )
       
  1028 
       
  1029 
       
  1030 class Queries5Tests(TestCase):
       
  1031     def setUp(self):
       
  1032         # Ordering by 'rank' gives us rank2, rank1, rank3. Ordering by the Meta.ordering
       
  1033         # will be rank3, rank2, rank1.
       
  1034         n1 = Note.objects.create(note='n1', misc='foo', id=1)
       
  1035         n2 = Note.objects.create(note='n2', misc='bar', id=2)
       
  1036         e1 = ExtraInfo.objects.create(info='e1', note=n1)
       
  1037         e2 = ExtraInfo.objects.create(info='e2', note=n2)
       
  1038         a1 = Author.objects.create(name='a1', num=1001, extra=e1)
       
  1039         a2 = Author.objects.create(name='a2', num=2002, extra=e1)
       
  1040         a3 = Author.objects.create(name='a3', num=3003, extra=e2)
       
  1041         self.rank1 = Ranking.objects.create(rank=2, author=a2)
       
  1042         Ranking.objects.create(rank=1, author=a3)
       
  1043         Ranking.objects.create(rank=3, author=a1)
       
  1044 
       
  1045     def test_ordering(self):
       
  1046         # Cross model ordering is possible in Meta, too.
       
  1047         self.assertQuerysetEqual(
       
  1048             Ranking.objects.all(),
       
  1049             ['<Ranking: 3: a1>', '<Ranking: 2: a2>', '<Ranking: 1: a3>']
       
  1050         )
       
  1051         self.assertQuerysetEqual(
       
  1052             Ranking.objects.all().order_by('rank'),
       
  1053             ['<Ranking: 1: a3>', '<Ranking: 2: a2>', '<Ranking: 3: a1>']
       
  1054         )
       
  1055 
       
  1056 
       
  1057         # Ordering of extra() pieces is possible, too and you can mix extra
       
  1058         # fields and model fields in the ordering.
       
  1059         self.assertQuerysetEqual(
       
  1060             Ranking.objects.extra(tables=['django_site'], order_by=['-django_site.id', 'rank']),
       
  1061             ['<Ranking: 1: a3>', '<Ranking: 2: a2>', '<Ranking: 3: a1>']
       
  1062         )
       
  1063 
       
  1064         qs = Ranking.objects.extra(select={'good': 'case when rank > 2 then 1 else 0 end'})
       
  1065         self.assertEqual(
       
  1066             [o.good for o in qs.extra(order_by=('-good',))],
       
  1067             [True, False, False]
       
  1068         )
       
  1069         self.assertQuerysetEqual(
       
  1070             qs.extra(order_by=('-good', 'id')),
       
  1071             ['<Ranking: 3: a1>', '<Ranking: 2: a2>', '<Ranking: 1: a3>']
       
  1072         )
       
  1073 
       
  1074         # Despite having some extra aliases in the query, we can still omit
       
  1075         # them in a values() query.
       
  1076         dicts = qs.values('id', 'rank').order_by('id')
       
  1077         self.assertEqual(
       
  1078             [d.items()[1] for d in dicts],
       
  1079             [('rank', 2), ('rank', 1), ('rank', 3)]
       
  1080         )
       
  1081 
       
  1082     def test_ticket7256(self):
       
  1083         # An empty values() call includes all aliases, including those from an
       
  1084         # extra()
       
  1085         qs = Ranking.objects.extra(select={'good': 'case when rank > 2 then 1 else 0 end'})
       
  1086         dicts = qs.values().order_by('id')
       
  1087         for d in dicts: del d['id']; del d['author_id']
       
  1088         self.assertEqual(
       
  1089             [sorted(d.items()) for d in dicts],
       
  1090             [[('good', 0), ('rank', 2)], [('good', 0), ('rank', 1)], [('good', 1), ('rank', 3)]]
       
  1091         )
       
  1092 
       
  1093     def test_ticket7045(self):
       
  1094         # Extra tables used to crash SQL construction on the second use.
       
  1095         qs = Ranking.objects.extra(tables=['django_site'])
       
  1096         qs.query.get_compiler(qs.db).as_sql()
       
  1097         # test passes if this doesn't raise an exception.
       
  1098         qs.query.get_compiler(qs.db).as_sql()
       
  1099 
       
  1100     def test_ticket9848(self):
       
  1101         # Make sure that updates which only filter on sub-tables don't
       
  1102         # inadvertently update the wrong records (bug #9848).
       
  1103 
       
  1104         # Make sure that the IDs from different tables don't happen to match.
       
  1105         self.assertQuerysetEqual(
       
  1106             Ranking.objects.filter(author__name='a1'),
       
  1107             ['<Ranking: 3: a1>']
       
  1108         )
       
  1109         self.assertEqual(
       
  1110             Ranking.objects.filter(author__name='a1').update(rank='4'),
       
  1111             1
       
  1112         )
       
  1113         r = Ranking.objects.filter(author__name='a1')[0]
       
  1114         self.assertNotEqual(r.id, r.author.id)
       
  1115         self.assertEqual(r.rank, 4)
       
  1116         r.rank = 3
       
  1117         r.save()
       
  1118         self.assertQuerysetEqual(
       
  1119             Ranking.objects.all(),
       
  1120             ['<Ranking: 3: a1>', '<Ranking: 2: a2>', '<Ranking: 1: a3>']
       
  1121         )
       
  1122 
       
  1123     def test_ticket5261(self):
       
  1124         self.assertQuerysetEqual(
       
  1125             Note.objects.exclude(Q()),
       
  1126             ['<Note: n1>', '<Note: n2>']
       
  1127         )
       
  1128 
       
  1129 
       
  1130 class SelectRelatedTests(TestCase):
       
  1131     def test_tickets_3045_3288(self):
       
  1132         # Once upon a time, select_related() with circular relations would loop
       
  1133         # infinitely if you forgot to specify "depth". Now we set an arbitrary
       
  1134         # default upper bound.
       
  1135         self.assertQuerysetEqual(X.objects.all(), [])
       
  1136         self.assertQuerysetEqual(X.objects.select_related(), [])
       
  1137 
       
  1138 
       
  1139 class SubclassFKTests(TestCase):
       
  1140     def test_ticket7778(self):
       
  1141         # Model subclasses could not be deleted if a nullable foreign key
       
  1142         # relates to a model that relates back.
       
  1143 
       
  1144         num_celebs = Celebrity.objects.count()
       
  1145         tvc = TvChef.objects.create(name="Huey")
       
  1146         self.assertEqual(Celebrity.objects.count(), num_celebs + 1)
       
  1147         Fan.objects.create(fan_of=tvc)
       
  1148         Fan.objects.create(fan_of=tvc)
       
  1149         tvc.delete()
       
  1150 
       
  1151         # The parent object should have been deleted as well.
       
  1152         self.assertEqual(Celebrity.objects.count(), num_celebs)
       
  1153 
       
  1154 
       
  1155 class CustomPkTests(TestCase):
       
  1156     def test_ticket7371(self):
       
  1157         self.assertQuerysetEqual(Related.objects.order_by('custom'), [])
       
  1158 
       
  1159 
       
  1160 class NullableRelOrderingTests(TestCase):
       
  1161     def test_ticket10028(self):
       
  1162         # Ordering by model related to nullable relations(!) should use outer
       
  1163         # joins, so that all results are included.
       
  1164         _ = Plaything.objects.create(name="p1")
       
  1165         self.assertQuerysetEqual(
       
  1166             Plaything.objects.all(),
       
  1167             ['<Plaything: p1>']
       
  1168         )
       
  1169 
       
  1170 
       
  1171 class DisjunctiveFilterTests(TestCase):
       
  1172     def setUp(self):
       
  1173         self.n1 = Note.objects.create(note='n1', misc='foo', id=1)
       
  1174         ExtraInfo.objects.create(info='e1', note=self.n1)
       
  1175 
       
  1176     def test_ticket7872(self):
       
  1177         # Another variation on the disjunctive filtering theme.
       
  1178 
       
  1179         # For the purposes of this regression test, it's important that there is no
       
  1180         # Join object releated to the LeafA we create.
       
  1181         LeafA.objects.create(data='first')
       
  1182         self.assertQuerysetEqual(LeafA.objects.all(), ['<LeafA: first>'])
       
  1183         self.assertQuerysetEqual(
       
  1184             LeafA.objects.filter(Q(data='first')|Q(join__b__data='second')),
       
  1185             ['<LeafA: first>']
       
  1186         )
       
  1187 
       
  1188     def test_ticket8283(self):
       
  1189         # Checking that applying filters after a disjunction works correctly.
       
  1190         self.assertQuerysetEqual(
       
  1191             (ExtraInfo.objects.filter(note=self.n1)|ExtraInfo.objects.filter(info='e2')).filter(note=self.n1),
       
  1192             ['<ExtraInfo: e1>']
       
  1193         )
       
  1194         self.assertQuerysetEqual(
       
  1195             (ExtraInfo.objects.filter(info='e2')|ExtraInfo.objects.filter(note=self.n1)).filter(note=self.n1),
       
  1196             ['<ExtraInfo: e1>']
       
  1197         )
       
  1198 
       
  1199 
       
  1200 class Queries6Tests(TestCase):
       
  1201     def setUp(self):
       
  1202         generic = NamedCategory.objects.create(name="Generic")
       
  1203         t1 = Tag.objects.create(name='t1', category=generic)
       
  1204         t2 = Tag.objects.create(name='t2', parent=t1, category=generic)
       
  1205         t3 = Tag.objects.create(name='t3', parent=t1)
       
  1206         t4 = Tag.objects.create(name='t4', parent=t3)
       
  1207         t5 = Tag.objects.create(name='t5', parent=t3)
       
  1208         n1 = Note.objects.create(note='n1', misc='foo', id=1)
       
  1209         ann1 = Annotation.objects.create(name='a1', tag=t1)
       
  1210         ann1.notes.add(n1)
       
  1211         ann2 = Annotation.objects.create(name='a2', tag=t4)
       
  1212 
       
  1213     # FIXME!! This next test causes really weird PostgreSQL behaviour, but it's
       
  1214     # only apparent much later when the full test suite runs. I don't understand
       
  1215     # what's going on here yet.
       
  1216     ##def test_slicing_and_cache_interaction(self):
       
  1217     ##    # We can do slicing beyond what is currently in the result cache,
       
  1218     ##    # too.
       
  1219     ##
       
  1220     ##    # We need to mess with the implementation internals a bit here to decrease the
       
  1221     ##    # cache fill size so that we don't read all the results at once.
       
  1222     ##    from django.db.models import query
       
  1223     ##    query.ITER_CHUNK_SIZE = 2
       
  1224     ##    qs = Tag.objects.all()
       
  1225     ##
       
  1226     ##    # Fill the cache with the first chunk.
       
  1227     ##    self.assertTrue(bool(qs))
       
  1228     ##    self.assertEqual(len(qs._result_cache), 2)
       
  1229     ##
       
  1230     ##    # Query beyond the end of the cache and check that it is filled out as required.
       
  1231     ##    self.assertEqual(repr(qs[4]), '<Tag: t5>')
       
  1232     ##    self.assertEqual(len(qs._result_cache), 5)
       
  1233     ##
       
  1234     ##    # But querying beyond the end of the result set will fail.
       
  1235     ##    self.assertRaises(IndexError, lambda: qs[100])
       
  1236 
       
  1237     def test_parallel_iterators(self):
       
  1238         # Test that parallel iterators work.
       
  1239         qs = Tag.objects.all()
       
  1240         i1, i2 = iter(qs), iter(qs)
       
  1241         self.assertEqual(repr(i1.next()), '<Tag: t1>')
       
  1242         self.assertEqual(repr(i1.next()), '<Tag: t2>')
       
  1243         self.assertEqual(repr(i2.next()), '<Tag: t1>')
       
  1244         self.assertEqual(repr(i2.next()), '<Tag: t2>')
       
  1245         self.assertEqual(repr(i2.next()), '<Tag: t3>')
       
  1246         self.assertEqual(repr(i1.next()), '<Tag: t3>')
       
  1247 
       
  1248         qs = X.objects.all()
       
  1249         self.assertEqual(bool(qs), False)
       
  1250         self.assertEqual(bool(qs), False)
       
  1251 
       
  1252     def test_nested_queries_sql(self):
       
  1253         # Nested queries should not evaluate the inner query as part of constructing the
       
  1254         # SQL (so we should see a nested query here, indicated by two "SELECT" calls).
       
  1255         qs = Annotation.objects.filter(notes__in=Note.objects.filter(note="xyzzy"))
       
  1256         self.assertEqual(
       
  1257             qs.query.get_compiler(qs.db).as_sql()[0].count('SELECT'),
       
  1258             2
       
  1259         )
       
  1260 
       
  1261     def test_tickets_8921_9188(self):
       
  1262         # Incorrect SQL was being generated for certain types of exclude()
       
  1263         # queries that crossed multi-valued relations (#8921, #9188 and some
       
  1264         # pre-emptively discovered cases).
       
  1265 
       
  1266         self.assertQuerysetEqual(
       
  1267             PointerA.objects.filter(connection__pointerb__id=1),
       
  1268             []
       
  1269         )
       
  1270         self.assertQuerysetEqual(
       
  1271             PointerA.objects.exclude(connection__pointerb__id=1),
       
  1272             []
       
  1273         )
       
  1274 
       
  1275         self.assertQuerysetEqual(
       
  1276             Tag.objects.exclude(children=None),
       
  1277             ['<Tag: t1>', '<Tag: t3>']
       
  1278         )
       
  1279 
       
  1280         # This example is tricky because the parent could be NULL, so only checking
       
  1281         # parents with annotations omits some results (tag t1, in this case).
       
  1282         self.assertQuerysetEqual(
       
  1283             Tag.objects.exclude(parent__annotation__name="a1"),
       
  1284             ['<Tag: t1>', '<Tag: t4>', '<Tag: t5>']
       
  1285         )
       
  1286 
       
  1287         # The annotation->tag link is single values and tag->children links is
       
  1288         # multi-valued. So we have to split the exclude filter in the middle
       
  1289         # and then optimise the inner query without losing results.
       
  1290         self.assertQuerysetEqual(
       
  1291             Annotation.objects.exclude(tag__children__name="t2"),
       
  1292             ['<Annotation: a2>']
       
  1293         )
       
  1294 
       
  1295         # Nested queries are possible (although should be used with care, since
       
  1296         # they have performance problems on backends like MySQL.
       
  1297 
       
  1298         self.assertQuerysetEqual(
       
  1299             Annotation.objects.filter(notes__in=Note.objects.filter(note="n1")),
       
  1300             ['<Annotation: a1>']
       
  1301         )
       
  1302 
       
  1303     def test_ticket3739(self):
       
  1304         # The all() method on querysets returns a copy of the queryset.
       
  1305         q1 = Tag.objects.order_by('name')
       
  1306         self.assertTrue(q1 is not q1.all())
       
  1307 
       
  1308 
       
  1309 class GeneratorExpressionTests(TestCase):
       
  1310     def test_ticket10432(self):
       
  1311         # Using an empty generator expression as the rvalue for an "__in"
       
  1312         # lookup is legal.
       
  1313         self.assertQuerysetEqual(
       
  1314             Note.objects.filter(pk__in=(x for x in ())),
       
  1315             []
       
  1316         )
       
  1317 
       
  1318 
       
  1319 class ComparisonTests(TestCase):
       
  1320     def setUp(self):
       
  1321         self.n1 = Note.objects.create(note='n1', misc='foo', id=1)
       
  1322         e1 = ExtraInfo.objects.create(info='e1', note=self.n1)
       
  1323         self.a2 = Author.objects.create(name='a2', num=2002, extra=e1)
       
  1324 
       
  1325     def test_ticket8597(self):
       
  1326         # Regression tests for case-insensitive comparisons
       
  1327         _ = Item.objects.create(name="a_b", created=datetime.datetime.now(), creator=self.a2, note=self.n1)
       
  1328         _ = Item.objects.create(name="x%y", created=datetime.datetime.now(), creator=self.a2, note=self.n1)
       
  1329         self.assertQuerysetEqual(
       
  1330             Item.objects.filter(name__iexact="A_b"),
       
  1331             ['<Item: a_b>']
       
  1332         )
       
  1333         self.assertQuerysetEqual(
       
  1334             Item.objects.filter(name__iexact="x%Y"),
       
  1335             ['<Item: x%y>']
       
  1336         )
       
  1337         self.assertQuerysetEqual(
       
  1338             Item.objects.filter(name__istartswith="A_b"),
       
  1339             ['<Item: a_b>']
       
  1340         )
       
  1341         self.assertQuerysetEqual(
       
  1342             Item.objects.filter(name__iendswith="A_b"),
       
  1343             ['<Item: a_b>']
       
  1344         )
       
  1345 
       
  1346 
       
  1347 class ExistsSql(TestCase):
       
  1348     def setUp(self):
       
  1349         settings.DEBUG = True
       
  1350 
       
  1351     def test_exists(self):
       
  1352         self.assertFalse(Tag.objects.exists())
       
  1353         # Ok - so the exist query worked - but did it include too many columns?
       
  1354         self.assertTrue("id" not in connection.queries[-1]['sql'] and "name" not in connection.queries[-1]['sql'])
       
  1355 
       
  1356     def tearDown(self):
       
  1357         settings.DEBUG = False
       
  1358 
       
  1359 
       
  1360 class QuerysetOrderedTests(unittest.TestCase):
       
  1361     """
       
  1362     Tests for the Queryset.ordered attribute.
       
  1363     """
       
  1364 
       
  1365     def test_no_default_or_explicit_ordering(self):
       
  1366         self.assertEqual(Annotation.objects.all().ordered, False)
       
  1367 
       
  1368     def test_cleared_default_ordering(self):
       
  1369         self.assertEqual(Tag.objects.all().ordered, True)
       
  1370         self.assertEqual(Tag.objects.all().order_by().ordered, False)
       
  1371 
       
  1372     def test_explicit_ordering(self):
       
  1373         self.assertEqual(Annotation.objects.all().order_by('id').ordered, True)
       
  1374 
       
  1375     def test_order_by_extra(self):
       
  1376         self.assertEqual(Annotation.objects.all().extra(order_by=['id']).ordered, True)
       
  1377 
       
  1378     def test_annotated_ordering(self):
       
  1379         qs = Annotation.objects.annotate(num_notes=Count('notes'))
       
  1380         self.assertEqual(qs.ordered, False)
       
  1381         self.assertEqual(qs.order_by('num_notes').ordered, True)
       
  1382 
       
  1383 
       
  1384 class SubqueryTests(TestCase):
       
  1385     def setUp(self):
       
  1386         DumbCategory.objects.create(id=1)
       
  1387         DumbCategory.objects.create(id=2)
       
  1388         DumbCategory.objects.create(id=3)
       
  1389 
       
  1390     def test_ordered_subselect(self):
       
  1391         "Subselects honor any manual ordering"
       
  1392         try:
       
  1393             query = DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[0:2])
       
  1394             self.assertEquals(set(query.values_list('id', flat=True)), set([2,3]))
       
  1395 
       
  1396             query = DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[:2])
       
  1397             self.assertEquals(set(query.values_list('id', flat=True)), set([2,3]))
       
  1398 
       
  1399             query = DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[2:])
       
  1400             self.assertEquals(set(query.values_list('id', flat=True)), set([1]))
       
  1401         except DatabaseError:
       
  1402             # Oracle and MySQL both have problems with sliced subselects.
       
  1403             # This prevents us from even evaluating this test case at all.
       
  1404             # Refs #10099
       
  1405             self.assertFalse(connections[DEFAULT_DB_ALIAS].features.allow_sliced_subqueries)
       
  1406 
       
  1407     def test_sliced_delete(self):
       
  1408         "Delete queries can safely contain sliced subqueries"
       
  1409         try:
       
  1410             DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[0:1]).delete()
       
  1411             self.assertEquals(set(DumbCategory.objects.values_list('id', flat=True)), set([1,2]))
       
  1412         except DatabaseError:
       
  1413             # Oracle and MySQL both have problems with sliced subselects.
       
  1414             # This prevents us from even evaluating this test case at all.
       
  1415             # Refs #10099
       
  1416             self.assertFalse(connections[DEFAULT_DB_ALIAS].features.allow_sliced_subqueries)
       
  1417 
       
  1418 
       
  1419 class CloneTests(TestCase):
       
  1420     def test_evaluated_queryset_as_argument(self):
       
  1421         "#13227 -- If a queryset is already evaluated, it can still be used as a query arg"
       
  1422         n = Note(note='Test1', misc='misc')
       
  1423         n.save()
       
  1424         e = ExtraInfo(info='good', note=n)
       
  1425         e.save()
       
  1426 
       
  1427         n_list = Note.objects.all()
       
  1428         # Evaluate the Note queryset, populating the query cache
       
  1429         list(n_list)
       
  1430         # Use the note queryset in a query, and evalute
       
  1431         # that query in a way that involves cloning.
       
  1432         try:
       
  1433             self.assertEquals(ExtraInfo.objects.filter(note__in=n_list)[0].info, 'good')
       
  1434         except:
       
  1435             self.fail('Query should be clonable')
       
  1436 
       
  1437 
       
  1438 class EmptyQuerySetTests(TestCase):
       
  1439     def test_emptyqueryset_values(self):
       
  1440         # #14366 -- Calling .values() on an EmptyQuerySet and then cloning that
       
  1441         # should not cause an error"
       
  1442         self.assertQuerysetEqual(
       
  1443             Number.objects.none().values('num').order_by('num'), []
       
  1444         )
       
  1445 
       
  1446     def test_values_subquery(self):
       
  1447         self.assertQuerysetEqual(
       
  1448             Number.objects.filter(pk__in=Number.objects.none().values("pk")),
       
  1449             []
       
  1450         )
       
  1451         self.assertQuerysetEqual(
       
  1452             Number.objects.filter(pk__in=Number.objects.none().values_list("pk")),
       
  1453             []
       
  1454         )
       
  1455 
       
  1456 
       
  1457 class ValuesQuerysetTests(BaseQuerysetTest):
       
  1458     def test_flat_values_lits(self):
       
  1459         Number.objects.create(num=72)
       
  1460         qs = Number.objects.values_list("num")
       
  1461         qs = qs.values_list("num", flat=True)
       
  1462         self.assertValueQuerysetEqual(
       
  1463             qs, [72]
       
  1464         )
       
  1465 
       
  1466 
       
  1467 class WeirdQuerysetSlicingTests(BaseQuerysetTest):
       
  1468     def setUp(self):
       
  1469         Number.objects.create(num=1)
       
  1470         Number.objects.create(num=2)
       
  1471 
       
  1472         Article.objects.create(name='one', created=datetime.datetime.now())
       
  1473         Article.objects.create(name='two', created=datetime.datetime.now())
       
  1474         Article.objects.create(name='three', created=datetime.datetime.now())
       
  1475         Article.objects.create(name='four', created=datetime.datetime.now())
       
  1476 
       
  1477     def test_tickets_7698_10202(self):
       
  1478         # People like to slice with '0' as the high-water mark.
       
  1479         self.assertQuerysetEqual(Article.objects.all()[0:0], [])
       
  1480         self.assertQuerysetEqual(Article.objects.all()[0:0][:10], [])
       
  1481         self.assertEqual(Article.objects.all()[:0].count(), 0)
       
  1482         self.assertRaisesMessage(
       
  1483             AssertionError,
       
  1484             'Cannot change a query once a slice has been taken.',
       
  1485             Article.objects.all()[:0].latest, 'created'
       
  1486         )
       
  1487 
       
  1488 
       
  1489 class EscapingTests(TestCase):
       
  1490     def test_ticket_7302(self):
       
  1491         # Reserved names are appropriately escaped
       
  1492         _ = ReservedName.objects.create(name='a', order=42)
       
  1493         ReservedName.objects.create(name='b', order=37)
       
  1494         self.assertQuerysetEqual(
       
  1495             ReservedName.objects.all().order_by('order'),
       
  1496             ['<ReservedName: b>', '<ReservedName: a>']
       
  1497         )
       
  1498         self.assertQuerysetEqual(
       
  1499             ReservedName.objects.extra(select={'stuff':'name'}, order_by=('order','stuff')),
       
  1500             ['<ReservedName: b>', '<ReservedName: a>']
       
  1501         )
       
  1502 
       
  1503 
       
  1504 # In Python 2.6 beta releases, exceptions raised in __len__ are swallowed
       
  1505 # (Python issue 1242657), so these cases return an empty list, rather than
       
  1506 # raising an exception. Not a lot we can do about that, unfortunately, due to
       
  1507 # the way Python handles list() calls internally. Thus, we skip the tests for
       
  1508 # Python 2.6.
       
  1509 if sys.version_info[:2] != (2, 6):
       
  1510     class OrderingLoopTests(BaseQuerysetTest):
       
  1511         def setUp(self):
       
  1512             generic = NamedCategory.objects.create(name="Generic")
       
  1513             t1 = Tag.objects.create(name='t1', category=generic)
       
  1514             t2 = Tag.objects.create(name='t2', parent=t1, category=generic)
       
  1515             t3 = Tag.objects.create(name='t3', parent=t1)
       
  1516             t4 = Tag.objects.create(name='t4', parent=t3)
       
  1517             t5 = Tag.objects.create(name='t5', parent=t3)
       
  1518 
       
  1519         def test_infinite_loop(self):
       
  1520             # If you're not careful, it's possible to introduce infinite loops via
       
  1521             # default ordering on foreign keys in a cycle. We detect that.
       
  1522             self.assertRaisesMessage(
       
  1523                 FieldError,
       
  1524                 'Infinite loop caused by ordering.',
       
  1525                 lambda: list(LoopX.objects.all()) # Force queryset evaluation with list()
       
  1526             )
       
  1527             self.assertRaisesMessage(
       
  1528                 FieldError,
       
  1529                 'Infinite loop caused by ordering.',
       
  1530                 lambda: list(LoopZ.objects.all()) # Force queryset evaluation with list()
       
  1531             )
       
  1532 
       
  1533             # Note that this doesn't cause an infinite loop, since the default
       
  1534             # ordering on the Tag model is empty (and thus defaults to using "id"
       
  1535             # for the related field).
       
  1536             self.assertEqual(len(Tag.objects.order_by('parent')), 5)
       
  1537 
       
  1538             # ... but you can still order in a non-recursive fashion amongst linked
       
  1539             # fields (the previous test failed because the default ordering was
       
  1540             # recursive).
       
  1541             self.assertQuerysetEqual(
       
  1542                 LoopX.objects.all().order_by('y__x__y__x__id'),
       
  1543                 []
       
  1544             )
       
  1545 
       
  1546 
       
  1547 # When grouping without specifying ordering, we add an explicit "ORDER BY NULL"
       
  1548 # portion in MySQL to prevent unnecessary sorting.
       
  1549 if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] == "django.db.backends.mysql":
       
  1550     class GroupingTests(TestCase):
       
  1551         def test_null_ordering_added(self):
       
  1552             query = Tag.objects.values_list('parent_id', flat=True).order_by().query
       
  1553             query.group_by = ['parent_id']
       
  1554             sql = query.get_compiler(DEFAULT_DB_ALIAS).as_sql()[0]
       
  1555             fragment = "ORDER BY "
       
  1556             pos = sql.find(fragment)
       
  1557             self.assertEqual(sql.find(fragment, pos + 1), -1)
       
  1558             self.assertEqual(sql.find("NULL", pos + len(fragment)), pos + len(fragment))
       
  1559 
       
  1560 
       
  1561 # Sqlite 3 does not support passing in more than 1000 parameters except by
       
  1562 # changing a parameter at compilation time.
       
  1563 if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != "django.db.backends.sqlite3":
       
  1564     class InLookupTests(TestCase):
       
  1565         def test_ticket14244(self):
       
  1566             # Test that the "in" lookup works with lists of 1000 items or more.
       
  1567             Number.objects.all().delete()
       
  1568             numbers = range(2500)
       
  1569             for num in numbers:
       
  1570                 _ = Number.objects.create(num=num)
       
  1571             self.assertEqual(
       
  1572                 Number.objects.filter(num__in=numbers[:1000]).count(),
       
  1573                 1000
       
  1574             )
       
  1575             self.assertEqual(
       
  1576                 Number.objects.filter(num__in=numbers[:1001]).count(),
       
  1577                 1001
       
  1578             )
       
  1579             self.assertEqual(
       
  1580                 Number.objects.filter(num__in=numbers[:2000]).count(),
       
  1581                 2000
       
  1582             )
       
  1583             self.assertEqual(
       
  1584                 Number.objects.filter(num__in=numbers).count(),
       
  1585                 2500
       
  1586             )