1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929 |
- from __future__ import absolute_import,unicode_literals
- import datetime
- from operator import attrgetter
- import pickle
- import sys
- import unittest
- from django.conf import settings
- from django.core.exceptions import FieldError
- from django.db import DatabaseError, connection, connections, DEFAULT_DB_ALIAS
- from django.db.models import Count, F, Q
- from django.db.models.sql.where import WhereNode, EverythingNode, NothingNode
- from django.db.models.sql.datastructures import EmptyResultSet
- from django.test import TestCase, skipUnlessDBFeature
- from django.test.utils import str_prefix
- from django.utils.datastructures import SortedDict
- from .models import (
- Annotation, Article, Author, Celebrity, Child, Cover, Detail, DumbCategory,
- ExtraInfo, Fan, Item, LeafA, Join, LeafB, LoopX, LoopZ, ManagedModel,
- Member, NamedCategory, Note, Number, Plaything, PointerA, Ranking, Related,
- Report, ReservedName, Tag, TvChef, Valid, X, Food, Eaten, Node, ObjectA,
- ObjectB, ObjectC, CategoryItem, SimpleCategory, SpecialCategory,
- OneToOneCategory, NullableName, ProxyCategory, SingleObject, RelatedObject,
- ModelA, ModelB, ModelC, ModelD, Responsibility, Job, JobResponsibilities,
- BaseA, FK1, Identifier, Program, Channel, Page, Paragraph, Chapter, Book,
- MyObject, Order, OrderItem)
- class BaseQuerysetTest(TestCase):
- def assertValueQuerysetEqual(self, qs, values):
- return self.assertQuerysetEqual(qs, values, transform=lambda x: x)
- class Queries1Tests(BaseQuerysetTest):
- def setUp(self):
- generic = NamedCategory.objects.create(name="Generic")
- self.t1 = Tag.objects.create(name='t1', category=generic)
- self.t2 = Tag.objects.create(name='t2', parent=self.t1, category=generic)
- self.t3 = Tag.objects.create(name='t3', parent=self.t1)
- t4 = Tag.objects.create(name='t4', parent=self.t3)
- self.t5 = Tag.objects.create(name='t5', parent=self.t3)
- self.n1 = Note.objects.create(note='n1', misc='foo', id=1)
- n2 = Note.objects.create(note='n2', misc='bar', id=2)
- self.n3 = Note.objects.create(note='n3', misc='foo', id=3)
- ann1 = Annotation.objects.create(name='a1', tag=self.t1)
- ann1.notes.add(self.n1)
- ann2 = Annotation.objects.create(name='a2', tag=t4)
- ann2.notes.add(n2, self.n3)
-
-
- self.e2 = ExtraInfo.objects.create(info='e2', note=n2, value=41)
- e1 = ExtraInfo.objects.create(info='e1', note=self.n1, value=42)
- self.a1 = Author.objects.create(name='a1', num=1001, extra=e1)
- self.a2 = Author.objects.create(name='a2', num=2002, extra=e1)
- a3 = Author.objects.create(name='a3', num=3003, extra=self.e2)
- self.a4 = Author.objects.create(name='a4', num=4004, extra=self.e2)
- self.time1 = datetime.datetime(2007, 12, 19, 22, 25, 0)
- self.time2 = datetime.datetime(2007, 12, 19, 21, 0, 0)
- time3 = datetime.datetime(2007, 12, 20, 22, 25, 0)
- time4 = datetime.datetime(2007, 12, 20, 21, 0, 0)
- self.i1 = Item.objects.create(name='one', created=self.time1, modified=self.time1, creator=self.a1, note=self.n3)
- self.i1.tags = [self.t1, self.t2]
- self.i2 = Item.objects.create(name='two', created=self.time2, creator=self.a2, note=n2)
- self.i2.tags = [self.t1, self.t3]
- self.i3 = Item.objects.create(name='three', created=time3, creator=self.a2, note=self.n3)
- i4 = Item.objects.create(name='four', created=time4, creator=self.a4, note=self.n3)
- i4.tags = [t4]
- self.r1 = Report.objects.create(name='r1', creator=self.a1)
- Report.objects.create(name='r2', creator=a3)
- Report.objects.create(name='r3')
-
-
- self.rank1 = Ranking.objects.create(rank=2, author=self.a2)
- Cover.objects.create(title="first", item=i4)
- Cover.objects.create(title="second", item=self.i2)
- def test_ticket1050(self):
- self.assertQuerysetEqual(
- Item.objects.filter(tags__isnull=True),
- ['<Item: three>']
- )
- self.assertQuerysetEqual(
- Item.objects.filter(tags__id__isnull=True),
- ['<Item: three>']
- )
- def test_ticket1801(self):
- self.assertQuerysetEqual(
- Author.objects.filter(item=self.i2),
- ['<Author: a2>']
- )
- self.assertQuerysetEqual(
- Author.objects.filter(item=self.i3),
- ['<Author: a2>']
- )
- self.assertQuerysetEqual(
- Author.objects.filter(item=self.i2) & Author.objects.filter(item=self.i3),
- ['<Author: a2>']
- )
- def test_ticket2306(self):
-
- query = Item.objects.filter(tags=self.t2).query
- self.assertTrue(query.LOUTER not in [x[2] for x in query.alias_map.values()])
- self.assertQuerysetEqual(
- Item.objects.filter(Q(tags=self.t1)).order_by('name'),
- ['<Item: one>', '<Item: two>']
- )
- self.assertQuerysetEqual(
- Item.objects.filter(Q(tags=self.t1)).filter(Q(tags=self.t2)),
- ['<Item: one>']
- )
- self.assertQuerysetEqual(
- Item.objects.filter(Q(tags=self.t1)).filter(Q(creator__name='fred')|Q(tags=self.t2)),
- ['<Item: one>']
- )
-
-
-
- self.assertQuerysetEqual(
- Item.objects.filter(Q(tags=self.t1) & Q(tags=self.t2)),
- []
- )
- self.assertQuerysetEqual(
- Item.objects.filter(Q(tags=self.t1), Q(creator__name='fred')|Q(tags=self.t2)),
- []
- )
- qs = Author.objects.filter(ranking__rank=2, ranking__id=self.rank1.id)
- self.assertQuerysetEqual(list(qs), ['<Author: a2>'])
- self.assertEqual(2, qs.query.count_active_tables(), 2)
- qs = Author.objects.filter(ranking__rank=2).filter(ranking__id=self.rank1.id)
- self.assertEqual(qs.query.count_active_tables(), 3)
- def test_ticket4464(self):
- self.assertQuerysetEqual(
- Item.objects.filter(tags=self.t1).filter(tags=self.t2),
- ['<Item: one>']
- )
- self.assertQuerysetEqual(
- Item.objects.filter(tags__in=[self.t1, self.t2]).distinct().order_by('name'),
- ['<Item: one>', '<Item: two>']
- )
- self.assertQuerysetEqual(
- Item.objects.filter(tags__in=[self.t1, self.t2]).filter(tags=self.t3),
- ['<Item: two>']
- )
-
- self.assertQuerysetEqual(
- Item.objects.filter(tags__in=[self.t1, self.t2]).order_by('name')[:3],
- ['<Item: one>', '<Item: one>', '<Item: two>']
- )
- self.assertQuerysetEqual(
- Item.objects.filter(tags__in=[self.t1, self.t2]).distinct().order_by('name')[:3],
- ['<Item: one>', '<Item: two>']
- )
- def test_tickets_2080_3592(self):
- self.assertQuerysetEqual(
- Author.objects.filter(item__name='one') | Author.objects.filter(name='a3'),
- ['<Author: a1>', '<Author: a3>']
- )
- self.assertQuerysetEqual(
- Author.objects.filter(Q(item__name='one') | Q(name='a3')),
- ['<Author: a1>', '<Author: a3>']
- )
- self.assertQuerysetEqual(
- Author.objects.filter(Q(name='a3') | Q(item__name='one')),
- ['<Author: a1>', '<Author: a3>']
- )
- self.assertQuerysetEqual(
- Author.objects.filter(Q(item__name='three') | Q(report__name='r3')),
- ['<Author: a2>']
- )
- def test_ticket6074(self):
-
-
- self.assertQuerysetEqual(Author.objects.filter(Q(id__in=[])), [])
- self.assertQuerysetEqual(
- Author.objects.filter(Q(id__in=[])|Q(id__in=[])),
- []
- )
- def test_tickets_1878_2939(self):
- self.assertEqual(Item.objects.values('creator').distinct().count(), 3)
-
-
- xx = Item(name='four', created=self.time1, creator=self.a2, note=self.n1)
- xx.save()
- self.assertEqual(
- Item.objects.exclude(name='two').values('creator', 'name').distinct().count(),
- 4
- )
- self.assertEqual(
- Item.objects.exclude(name='two').extra(select={'foo': '%s'}, select_params=(1,)).values('creator', 'name', 'foo').distinct().count(),
- 4
- )
- self.assertEqual(
- Item.objects.exclude(name='two').extra(select={'foo': '%s'}, select_params=(1,)).values('creator', 'name').distinct().count(),
- 4
- )
- xx.delete()
- def test_ticket7323(self):
- self.assertEqual(Item.objects.values('creator', 'name').count(), 4)
- def test_ticket2253(self):
- q1 = Item.objects.order_by('name')
- q2 = Item.objects.filter(id=self.i1.id)
- self.assertQuerysetEqual(
- q1,
- ['<Item: four>', '<Item: one>', '<Item: three>', '<Item: two>']
- )
- self.assertQuerysetEqual(q2, ['<Item: one>'])
- self.assertQuerysetEqual(
- (q1 | q2).order_by('name'),
- ['<Item: four>', '<Item: one>', '<Item: three>', '<Item: two>']
- )
- self.assertQuerysetEqual((q1 & q2).order_by('name'), ['<Item: one>'])
- q1 = Item.objects.filter(tags=self.t1)
- q2 = Item.objects.filter(note=self.n3, tags=self.t2)
- q3 = Item.objects.filter(creator=self.a4)
- self.assertQuerysetEqual(
- ((q1 & q2) | q3).order_by('name'),
- ['<Item: four>', '<Item: one>']
- )
- def test_order_by_tables(self):
- q1 = Item.objects.order_by('name')
- q2 = Item.objects.filter(id=self.i1.id)
- list(q2)
- combined_query = (q1 & q2).order_by('name').query
- self.assertEqual(len([
- t for t in combined_query.tables if combined_query.alias_refcount[t]
- ]), 1)
- def test_order_by_join_unref(self):
- """
- This test is related to the above one, testing that there aren't
- old JOINs in the query.
- """
- qs = Celebrity.objects.order_by('greatest_fan__fan_of')
- self.assertIn('OUTER JOIN', str(qs.query))
- qs = qs.order_by('id')
- self.assertNotIn('OUTER JOIN', str(qs.query))
- def test_tickets_4088_4306(self):
- self.assertQuerysetEqual(
- Report.objects.filter(creator=1001),
- ['<Report: r1>']
- )
- self.assertQuerysetEqual(
- Report.objects.filter(creator__num=1001),
- ['<Report: r1>']
- )
- self.assertQuerysetEqual(Report.objects.filter(creator__id=1001), [])
- self.assertQuerysetEqual(
- Report.objects.filter(creator__id=self.a1.id),
- ['<Report: r1>']
- )
- self.assertQuerysetEqual(
- Report.objects.filter(creator__name='a1'),
- ['<Report: r1>']
- )
- def test_ticket4510(self):
- self.assertQuerysetEqual(
- Author.objects.filter(report__name='r1'),
- ['<Author: a1>']
- )
- def test_ticket7378(self):
- self.assertQuerysetEqual(self.a1.report_set.all(), ['<Report: r1>'])
- def test_tickets_5324_6704(self):
- self.assertQuerysetEqual(
- Item.objects.filter(tags__name='t4'),
- ['<Item: four>']
- )
- self.assertQuerysetEqual(
- Item.objects.exclude(tags__name='t4').order_by('name').distinct(),
- ['<Item: one>', '<Item: three>', '<Item: two>']
- )
- self.assertQuerysetEqual(
- Item.objects.exclude(tags__name='t4').order_by('name').distinct().reverse(),
- ['<Item: two>', '<Item: three>', '<Item: one>']
- )
- self.assertQuerysetEqual(
- Author.objects.exclude(item__name='one').distinct().order_by('name'),
- ['<Author: a2>', '<Author: a3>', '<Author: a4>']
- )
-
-
- self.assertQuerysetEqual(
- Item.objects.exclude(tags__name='t1').order_by('name'),
- ['<Item: four>', '<Item: three>']
- )
- self.assertQuerysetEqual(
- Item.objects.exclude(tags__name='t1').exclude(tags__name='t4'),
- ['<Item: three>']
- )
-
- query = Item.objects.exclude(creator__in=[self.a1, self.a2]).query
- self.assertTrue(query.LOUTER not in [x[2] for x in query.alias_map.values()])
-
-
-
-
- qs = Author.objects.filter(id=self.a1.id).filter(Q(extra__note=self.n1)|Q(item__note=self.n3))
- self.assertEqual(
- len([x[2] for x in qs.query.alias_map.values() if x[2] == query.LOUTER and qs.query.alias_refcount[x[1]]]),
- 1
- )
-
- self.assertQuerysetEqual(
- Tag.objects.filter(parent__isnull=True).order_by('name'),
- ['<Tag: t1>']
- )
- self.assertQuerysetEqual(
- Tag.objects.exclude(parent__isnull=True).order_by('name'),
- ['<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>']
- )
- self.assertQuerysetEqual(
- Tag.objects.exclude(Q(parent__name='t1') | Q(parent__isnull=True)).order_by('name'),
- ['<Tag: t4>', '<Tag: t5>']
- )
- self.assertQuerysetEqual(
- Tag.objects.exclude(Q(parent__isnull=True) | Q(parent__name='t1')).order_by('name'),
- ['<Tag: t4>', '<Tag: t5>']
- )
- self.assertQuerysetEqual(
- Tag.objects.exclude(Q(parent__parent__isnull=True)).order_by('name'),
- ['<Tag: t4>', '<Tag: t5>']
- )
- self.assertQuerysetEqual(
- Tag.objects.filter(~Q(parent__parent__isnull=True)).order_by('name'),
- ['<Tag: t4>', '<Tag: t5>']
- )
- def test_ticket2091(self):
- t = Tag.objects.get(name='t4')
- self.assertQuerysetEqual(
- Item.objects.filter(tags__in=[t]),
- ['<Item: four>']
- )
- def test_heterogeneous_qs_combination(self):
-
-
- self.assertRaisesMessage(
- AssertionError,
- 'Cannot combine queries on two different base models.',
- lambda: Author.objects.all() & Tag.objects.all()
- )
- self.assertRaisesMessage(
- AssertionError,
- 'Cannot combine queries on two different base models.',
- lambda: Author.objects.all() | Tag.objects.all()
- )
- def test_ticket3141(self):
- self.assertEqual(Author.objects.extra(select={'foo': '1'}).count(), 4)
- self.assertEqual(
- Author.objects.extra(select={'foo': '%s'}, select_params=(1,)).count(),
- 4
- )
- def test_ticket2400(self):
- self.assertQuerysetEqual(
- Author.objects.filter(item__isnull=True),
- ['<Author: a3>']
- )
- self.assertQuerysetEqual(
- Tag.objects.filter(item__isnull=True),
- ['<Tag: t5>']
- )
- def test_ticket2496(self):
- self.assertQuerysetEqual(
- Item.objects.extra(tables=['queries_author']).select_related().order_by('name')[:1],
- ['<Item: four>']
- )
- def test_tickets_2076_7256(self):
-
-
- self.assertQuerysetEqual(
- Item.objects.order_by('note__note', 'name'),
- ['<Item: two>', '<Item: four>', '<Item: one>', '<Item: three>']
- )
-
-
- self.assertQuerysetEqual(
- Author.objects.order_by('extra', '-name'),
- ['<Author: a2>', '<Author: a1>', '<Author: a4>', '<Author: a3>']
- )
-
-
- self.assertQuerysetEqual(
- Cover.objects.all(),
- ['<Cover: first>', '<Cover: second>']
- )
-
-
- self.assertQuerysetEqual(
- Item.objects.order_by('creator', 'name'),
- ['<Item: one>', '<Item: three>', '<Item: two>', '<Item: four>']
- )
-
-
-
- self.assertQuerysetEqual(
- Item.objects.filter(tags__isnull=False).order_by('tags', 'id'),
- ['<Item: one>', '<Item: two>', '<Item: one>', '<Item: two>', '<Item: four>']
- )
-
-
-
- qs = Item.objects.order_by('name')
- self.assertQuerysetEqual(
- qs,
- ['<Item: four>', '<Item: one>', '<Item: three>', '<Item: two>']
- )
- self.assertEqual(len(qs.query.tables), 1)
- def test_tickets_2874_3002(self):
- qs = Item.objects.select_related().order_by('note__note', 'name')
- self.assertQuerysetEqual(
- qs,
- ['<Item: two>', '<Item: four>', '<Item: one>', '<Item: three>']
- )
-
-
- self.assertTrue(repr(qs[0].note), '<Note: n2>')
- self.assertEqual(repr(qs[0].creator.extra.note), '<Note: n1>')
- def test_ticket3037(self):
- self.assertQuerysetEqual(
- Item.objects.filter(Q(creator__name='a3', name='two')|Q(creator__name='a4', name='four')),
- ['<Item: four>']
- )
- def test_tickets_5321_7070(self):
-
-
-
-
-
- self.assertValueQuerysetEqual(
- Note.objects.values('misc').distinct().order_by('note', '-misc'),
- [{'misc': 'foo'}, {'misc': 'bar'}, {'misc': 'foo'}]
- )
- def test_ticket4358(self):
-
-
-
-
-
- self.assertTrue('note_id' in ExtraInfo.objects.values()[0])
-
- self.assertValueQuerysetEqual(
- ExtraInfo.objects.values('note_id'),
- [{'note_id': 1}, {'note_id': 2}]
- )
-
- self.assertValueQuerysetEqual(
- ExtraInfo.objects.values('note'),
- [{'note': 1}, {'note': 2}]
- )
- def test_ticket2902(self):
-
-
-
-
- s = [('a', '%s'), ('b', '%s')]
- params = ['one', 'two']
- if {'a': 1, 'b': 2}.keys() == ['a', 'b']:
- s.reverse()
- params.reverse()
-
-
-
- d = Item.objects.extra(select=SortedDict(s), select_params=params).values('a', 'b')[0]
- self.assertEqual(d, {'a': 'one', 'b': 'two'})
-
- l = Item.objects.extra(select={'count': 'select count(*) from queries_item_tags where queries_item_tags.item_id = queries_item.id'}).order_by('-count')
- self.assertEqual([o.count for o in l], [2, 2, 1, 0])
- def test_ticket6154(self):
-
- self.assertQuerysetEqual(
- Author.objects.filter(id=self.a1.id).filter(Q(extra__note=self.n1)|Q(item__note=self.n3)),
- ['<Author: a1>']
- )
- self.assertQuerysetEqual(
- Author.objects.filter(Q(extra__note=self.n1)|Q(item__note=self.n3)).filter(id=self.a1.id),
- ['<Author: a1>']
- )
- def test_ticket6981(self):
- self.assertQuerysetEqual(
- Tag.objects.select_related('parent').order_by('name'),
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>']
- )
- def test_ticket9926(self):
- self.assertQuerysetEqual(
- Tag.objects.select_related("parent", "category").order_by('name'),
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>']
- )
- self.assertQuerysetEqual(
- Tag.objects.select_related('parent', "parent__category").order_by('name'),
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>']
- )
- def test_tickets_6180_6203(self):
-
- self.assertEqual(Item.objects.count(), 4)
- self.assertEqual(Item.objects.datetimes('created', 'month').count(), 1)
- self.assertEqual(Item.objects.datetimes('created', 'day').count(), 2)
- self.assertEqual(len(Item.objects.datetimes('created', 'day')), 2)
- self.assertEqual(Item.objects.datetimes('created', 'day')[0], datetime.datetime(2007, 12, 19, 0, 0))
- def test_tickets_7087_12242(self):
-
- self.assertQuerysetEqual(
- Item.objects.datetimes('created', 'day').extra(select={'a': 1}),
- ['datetime.datetime(2007, 12, 19, 0, 0)', 'datetime.datetime(2007, 12, 20, 0, 0)']
- )
- self.assertQuerysetEqual(
- Item.objects.extra(select={'a': 1}).datetimes('created', 'day'),
- ['datetime.datetime(2007, 12, 19, 0, 0)', 'datetime.datetime(2007, 12, 20, 0, 0)']
- )
- name="one"
- self.assertQuerysetEqual(
- Item.objects.datetimes('created', 'day').extra(where=['name=%s'], params=[name]),
- ['datetime.datetime(2007, 12, 19, 0, 0)']
- )
- self.assertQuerysetEqual(
- Item.objects.extra(where=['name=%s'], params=[name]).datetimes('created', 'day'),
- ['datetime.datetime(2007, 12, 19, 0, 0)']
- )
- def test_ticket7155(self):
-
- self.assertQuerysetEqual(
- Item.objects.datetimes('modified', 'day'),
- ['datetime.datetime(2007, 12, 19, 0, 0)']
- )
- def test_ticket7098(self):
-
-
- self.assertValueQuerysetEqual(
- Item.objects.values('note__note').order_by('queries_note.note', 'id'),
- [{'note__note': 'n2'}, {'note__note': 'n3'}, {'note__note': 'n3'}, {'note__note': 'n3'}]
- )
- def test_ticket7096(self):
-
- self.assertQuerysetEqual(
- Tag.objects.filter(parent=self.t1, name='t3').order_by('name'),
- ['<Tag: t3>']
- )
- self.assertQuerysetEqual(
- Tag.objects.exclude(parent=self.t1, name='t3').order_by('name'),
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t4>', '<Tag: t5>']
- )
- self.assertQuerysetEqual(
- Item.objects.exclude(tags__name='t1', name='one').order_by('name').distinct(),
- ['<Item: four>', '<Item: three>', '<Item: two>']
- )
- self.assertQuerysetEqual(
- Item.objects.filter(name__in=['three', 'four']).exclude(tags__name='t1').order_by('name'),
- ['<Item: four>', '<Item: three>']
- )
-
- self.assertQuerysetEqual(
- Item.objects.exclude(~Q(tags__name='t1', name='one')),
- ['<Item: one>']
- )
- self.assertQuerysetEqual(
- Item.objects.filter(~Q(tags__name='t1', name='one'), name='two'),
- ['<Item: two>']
- )
- self.assertQuerysetEqual(
- Item.objects.exclude(~Q(tags__name='t1', name='one'), name='two'),
- ['<Item: four>', '<Item: one>', '<Item: three>']
- )
- def test_tickets_7204_7506(self):
-
-
- pickle.dumps(Item.objects.all())
- def test_ticket7813(self):
-
-
-
- qs = Item.objects.select_related()
- query = qs.query.get_compiler(qs.db).as_sql()[0]
- query2 = pickle.loads(pickle.dumps(qs.query))
- self.assertEqual(
- query2.get_compiler(qs.db).as_sql()[0],
- query
- )
- def test_deferred_load_qs_pickling(self):
-
- qs = Item.objects.defer('name', 'creator')
- q2 = pickle.loads(pickle.dumps(qs))
- self.assertEqual(list(qs), list(q2))
- q3 = pickle.loads(pickle.dumps(qs, pickle.HIGHEST_PROTOCOL))
- self.assertEqual(list(qs), list(q3))
- def test_ticket7277(self):
- self.assertQuerysetEqual(
- self.n1.annotation_set.filter(Q(tag=self.t5) | Q(tag__children=self.t5) | Q(tag__children__children=self.t5)),
- ['<Annotation: a1>']
- )
- def test_tickets_7448_7707(self):
-
-
- self.assertQuerysetEqual(
- Item.objects.filter(created__in=[self.time1, self.time2]),
- ['<Item: one>', '<Item: two>']
- )
- def test_ticket7235(self):
-
- Eaten.objects.create(meal='m')
- q = Eaten.objects.none()
- with self.assertNumQueries(0):
- self.assertQuerysetEqual(q.all(), [])
- self.assertQuerysetEqual(q.filter(meal='m'), [])
- self.assertQuerysetEqual(q.exclude(meal='m'), [])
- self.assertQuerysetEqual(q.complex_filter({'pk': 1}), [])
- self.assertQuerysetEqual(q.select_related('food'), [])
- self.assertQuerysetEqual(q.annotate(Count('food')), [])
- self.assertQuerysetEqual(q.order_by('meal', 'food'), [])
- self.assertQuerysetEqual(q.distinct(), [])
- self.assertQuerysetEqual(
- q.extra(select={'foo': "1"}),
- []
- )
- q.query.low_mark = 1
- self.assertRaisesMessage(
- AssertionError,
- 'Cannot change a query once a slice has been taken',
- q.extra, select={'foo': "1"}
- )
- self.assertQuerysetEqual(q.reverse(), [])
- self.assertQuerysetEqual(q.defer('meal'), [])
- self.assertQuerysetEqual(q.only('meal'), [])
- def test_ticket7791(self):
-
-
- self.assertEqual(
- len(Note.objects.order_by('extrainfo__info').distinct()),
- 3
- )
-
- qs = Item.objects.datetimes('created', 'month')
- _ = pickle.loads(pickle.dumps(qs))
- def test_ticket9997(self):
-
-
-
- self.assertQuerysetEqual(
- Tag.objects.filter(name__in=Tag.objects.filter(parent=self.t1).values('name')),
- ['<Tag: t2>', '<Tag: t3>']
- )
-
- self.assertRaisesMessage(
- TypeError,
- 'Cannot use a multi-field ValuesQuerySet as a filter value.',
- lambda: Tag.objects.filter(name__in=Tag.objects.filter(parent=self.t1).values('name', 'id'))
- )
- self.assertRaisesMessage(
- TypeError,
- 'Cannot use a multi-field ValuesListQuerySet as a filter value.',
- lambda: Tag.objects.filter(name__in=Tag.objects.filter(parent=self.t1).values_list('name', 'id'))
- )
- def test_ticket9985(self):
-
- self.assertValueQuerysetEqual(
- Note.objects.values_list("note", flat=True).values("id").order_by("id"),
- [{'id': 1}, {'id': 2}, {'id': 3}]
- )
- self.assertQuerysetEqual(
- Annotation.objects.filter(notes__in=Note.objects.filter(note="n1").values_list('note').values('id')),
- ['<Annotation: a1>']
- )
- def test_ticket10205(self):
-
-
- self.assertEqual(Tag.objects.filter(name__in=()).update(name="foo"), 0)
- def test_ticket10432(self):
-
- def f():
- return iter([])
- n_obj = Note.objects.all()[0]
- def g():
- for i in [n_obj.pk]:
- yield i
- self.assertQuerysetEqual(Note.objects.filter(pk__in=f()), [])
- self.assertEqual(list(Note.objects.filter(pk__in=g())), [n_obj])
- def test_ticket10742(self):
-
- subq = Author.objects.filter(num__lt=3000)
- qs = Author.objects.filter(pk__in=subq)
- self.assertQuerysetEqual(qs, ['<Author: a1>', '<Author: a2>'])
-
- self.assertTrue(subq._result_cache is None)
- subq = Author.objects.filter(num__lt=3000)
- qs = Author.objects.exclude(pk__in=subq)
- self.assertQuerysetEqual(qs, ['<Author: a3>', '<Author: a4>'])
-
- self.assertTrue(subq._result_cache is None)
- subq = Author.objects.filter(num__lt=3000)
- self.assertQuerysetEqual(
- Author.objects.filter(Q(pk__in=subq) & Q(name='a1')),
- ['<Author: a1>']
- )
-
- self.assertTrue(subq._result_cache is None)
- def test_ticket7076(self):
-
- self.assertQuerysetEqual(
- Item.objects.exclude(modified=self.time1).order_by('name'),
- ['<Item: four>', '<Item: three>', '<Item: two>']
- )
- self.assertQuerysetEqual(
- Tag.objects.exclude(parent__name=self.t1.name),
- ['<Tag: t1>', '<Tag: t4>', '<Tag: t5>']
- )
- def test_ticket7181(self):
-
-
-
- self.assertEqual(len(Tag.objects.order_by('parent__name')), 5)
-
- self.assertQuerysetEqual(
- Note.objects.none() | Note.objects.all(),
- ['<Note: n1>', '<Note: n2>', '<Note: n3>']
- )
- self.assertQuerysetEqual(
- Note.objects.all() | Note.objects.none(),
- ['<Note: n1>', '<Note: n2>', '<Note: n3>']
- )
- self.assertQuerysetEqual(Note.objects.none() & Note.objects.all(), [])
- self.assertQuerysetEqual(Note.objects.all() & Note.objects.none(), [])
- def test_ticket9411(self):
-
-
- qs = Tag.objects.values_list('id', flat=True).order_by('id')
- qs.query.bump_prefix()
- first = qs[0]
- self.assertEqual(list(qs), list(range(first, first+5)))
- def test_ticket8439(self):
-
-
- self.assertQuerysetEqual(
- Author.objects.filter(Q(item__note__extrainfo=self.e2)|Q(report=self.r1, name='xyz')),
- ['<Author: a2>']
- )
- self.assertQuerysetEqual(
- Author.objects.filter(Q(report=self.r1, name='xyz')|Q(item__note__extrainfo=self.e2)),
- ['<Author: a2>']
- )
- self.assertQuerysetEqual(
- Annotation.objects.filter(Q(tag__parent=self.t1)|Q(notes__note='n1', name='a1')),
- ['<Annotation: a1>']
- )
- xx = ExtraInfo.objects.create(info='xx', note=self.n3)
- self.assertQuerysetEqual(
- Note.objects.filter(Q(extrainfo__author=self.a1)|Q(extrainfo=xx)),
- ['<Note: n1>', '<Note: n3>']
- )
- q = Note.objects.filter(Q(extrainfo__author=self.a1)|Q(extrainfo=xx)).query
- self.assertEqual(
- len([x[2] for x in q.alias_map.values() if x[2] == q.LOUTER and q.alias_refcount[x[1]]]),
- 1
- )
- def test_ticket17429(self):
- """
- Ensure that Meta.ordering=None works the same as Meta.ordering=[]
- """
- original_ordering = Tag._meta.ordering
- Tag._meta.ordering = None
- try:
- self.assertQuerysetEqual(
- Tag.objects.all(),
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'],
- ordered=False
- )
- finally:
- Tag._meta.ordering = original_ordering
- def test_exclude(self):
- self.assertQuerysetEqual(
- Item.objects.exclude(tags__name='t4'),
- [repr(i) for i in Item.objects.filter(~Q(tags__name='t4'))])
- self.assertQuerysetEqual(
- Item.objects.exclude(Q(tags__name='t4')|Q(tags__name='t3')),
- [repr(i) for i in Item.objects.filter(~(Q(tags__name='t4')|Q(tags__name='t3')))])
- self.assertQuerysetEqual(
- Item.objects.exclude(Q(tags__name='t4')|~Q(tags__name='t3')),
- [repr(i) for i in Item.objects.filter(~(Q(tags__name='t4')|~Q(tags__name='t3')))])
- def test_nested_exclude(self):
- self.assertQuerysetEqual(
- Item.objects.exclude(~Q(tags__name='t4')),
- [repr(i) for i in Item.objects.filter(~~Q(tags__name='t4'))])
- def test_double_exclude(self):
- self.assertQuerysetEqual(
- Item.objects.filter(Q(tags__name='t4')),
- [repr(i) for i in Item.objects.filter(~~Q(tags__name='t4'))])
- self.assertQuerysetEqual(
- Item.objects.filter(Q(tags__name='t4')),
- [repr(i) for i in Item.objects.filter(~Q(~Q(tags__name='t4')))])
- def test_exclude_in(self):
- self.assertQuerysetEqual(
- Item.objects.exclude(Q(tags__name__in=['t4', 't3'])),
- [repr(i) for i in Item.objects.filter(~Q(tags__name__in=['t4', 't3']))])
- self.assertQuerysetEqual(
- Item.objects.filter(Q(tags__name__in=['t4', 't3'])),
- [repr(i) for i in Item.objects.filter(~~Q(tags__name__in=['t4', 't3']))])
- def test_ticket_10790_1(self):
-
-
- q = Tag.objects.filter(parent__isnull=True)
- self.assertQuerysetEqual(q, ['<Tag: t1>'])
- self.assertTrue('JOIN' not in str(q.query))
- q = Tag.objects.filter(parent__isnull=False)
- self.assertQuerysetEqual(
- q,
- ['<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'],
- )
- self.assertTrue('JOIN' not in str(q.query))
- q = Tag.objects.exclude(parent__isnull=True)
- self.assertQuerysetEqual(
- q,
- ['<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'],
- )
- self.assertTrue('JOIN' not in str(q.query))
- q = Tag.objects.exclude(parent__isnull=False)
- self.assertQuerysetEqual(q, ['<Tag: t1>'])
- self.assertTrue('JOIN' not in str(q.query))
- q = Tag.objects.exclude(parent__parent__isnull=False)
- self.assertQuerysetEqual(
- q,
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>'],
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 1)
- self.assertTrue('INNER JOIN' not in str(q.query))
- def test_ticket_10790_2(self):
-
-
- q = Tag.objects.filter(parent__parent__isnull=False)
- self.assertQuerysetEqual(
- q,
- ['<Tag: t4>', '<Tag: t5>'],
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 0)
- self.assertTrue(str(q.query).count('INNER JOIN') == 1)
-
- q = Tag.objects.filter(parent__parent=self.t1)
- self.assertQuerysetEqual(
- q,
- ['<Tag: t4>', '<Tag: t5>'],
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 0)
- self.assertTrue(str(q.query).count('INNER JOIN') == 1)
- def test_ticket_10790_3(self):
-
- q = NamedCategory.objects.filter(tag__isnull=True)
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 1)
-
- self.assertTrue(str(q.query).count('INNER JOIN') == 1)
- self.assertQuerysetEqual(q, [])
-
-
- q = NamedCategory.objects.filter(tag__parent__isnull=True)
- self.assertTrue(str(q.query).count('INNER JOIN') == 1)
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 1)
- self.assertQuerysetEqual( q, ['<NamedCategory: NamedCategory object>'])
- def test_ticket_10790_4(self):
-
- q = Author.objects.filter(item__tags__isnull=True)
- self.assertQuerysetEqual(
- q,
- ['<Author: a2>', '<Author: a3>'],
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 2)
- self.assertTrue('INNER JOIN' not in str(q.query))
- q = Author.objects.filter(item__tags__parent__isnull=True)
- self.assertQuerysetEqual(
- q,
- ['<Author: a1>', '<Author: a2>', '<Author: a2>', '<Author: a3>'],
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 3)
- self.assertTrue('INNER JOIN' not in str(q.query))
- def test_ticket_10790_5(self):
-
- q = Author.objects.filter(item__tags__isnull=False)
- self.assertQuerysetEqual(
- q,
- ['<Author: a1>', '<Author: a1>', '<Author: a2>', '<Author: a2>', '<Author: a4>']
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 0)
- self.assertTrue(str(q.query).count('INNER JOIN') == 2)
- q = Author.objects.filter(item__tags__parent__isnull=False)
- self.assertQuerysetEqual(
- q,
- ['<Author: a1>', '<Author: a2>', '<Author: a4>']
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 0)
- self.assertTrue(str(q.query).count('INNER JOIN') == 3)
- q = Author.objects.filter(item__tags__parent__parent__isnull=False)
- self.assertQuerysetEqual(
- q,
- ['<Author: a4>']
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 0)
- self.assertTrue(str(q.query).count('INNER JOIN') == 4)
- def test_ticket_10790_6(self):
-
-
- q = Author.objects.filter(item__tags__parent__parent__isnull=True)
- self.assertQuerysetEqual(
- q,
- ['<Author: a1>', '<Author: a1>', '<Author: a2>', '<Author: a2>',
- '<Author: a2>', '<Author: a3>']
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 4)
- self.assertTrue(str(q.query).count('INNER JOIN') == 0)
- q = Author.objects.filter(item__tags__parent__isnull=True)
- self.assertQuerysetEqual(
- q,
- ['<Author: a1>', '<Author: a2>', '<Author: a2>', '<Author: a3>']
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 3)
- self.assertTrue(str(q.query).count('INNER JOIN') == 0)
- def test_ticket_10790_7(self):
-
- q = Author.objects.filter(item__isnull=True)
- self.assertQuerysetEqual(
- q,
- ['<Author: a3>']
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 1)
- self.assertTrue(str(q.query).count('INNER JOIN') == 0)
- q = Author.objects.filter(item__isnull=False)
- self.assertQuerysetEqual(
- q,
- ['<Author: a1>', '<Author: a2>', '<Author: a2>', '<Author: a4>']
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 0)
- self.assertTrue(str(q.query).count('INNER JOIN') == 1)
- def test_ticket_10790_8(self):
-
- q = Tag.objects.filter(Q(parent__isnull=True) | Q(parent=self.t1))
- self.assertQuerysetEqual(
- q,
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>']
- )
- self.assertTrue(str(q.query).count('LEFT OUTER JOIN') == 0)
- self.assertTrue(str(q.query).count('INNER JOIN') == 0)
- def test_ticket_10790_combine(self):
-
- q1 = Tag.objects.filter(parent__isnull=True)
- q2 = Tag.objects.filter(parent__isnull=False)
- q3 = q1 | q2
- self.assertQuerysetEqual(
- q3,
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>', '<Tag: t4>', '<Tag: t5>'],
- )
- self.assertTrue(str(q3.query).count('LEFT OUTER JOIN') == 0)
- self.assertTrue(str(q3.query).count('INNER JOIN') == 0)
- q3 = q1 & q2
- self.assertQuerysetEqual(q3, [])
- self.assertTrue(str(q3.query).count('LEFT OUTER JOIN') == 0)
- self.assertTrue(str(q3.query).count('INNER JOIN') == 0)
- q2 = Tag.objects.filter(parent=self.t1)
- q3 = q1 | q2
- self.assertQuerysetEqual(
- q3,
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>']
- )
- self.assertTrue(str(q3.query).count('LEFT OUTER JOIN') == 0)
- self.assertTrue(str(q3.query).count('INNER JOIN') == 0)
- q3 = q2 | q1
- self.assertQuerysetEqual(
- q3,
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>']
- )
- self.assertTrue(str(q3.query).count('LEFT OUTER JOIN') == 0)
- self.assertTrue(str(q3.query).count('INNER JOIN') == 0)
- q1 = Tag.objects.filter(parent__isnull=True)
- q2 = Tag.objects.filter(parent__parent__isnull=True)
- q3 = q1 | q2
- self.assertQuerysetEqual(
- q3,
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>']
- )
- self.assertTrue(str(q3.query).count('LEFT OUTER JOIN') == 1)
- self.assertTrue(str(q3.query).count('INNER JOIN') == 0)
- q3 = q2 | q1
- self.assertQuerysetEqual(
- q3,
- ['<Tag: t1>', '<Tag: t2>', '<Tag: t3>']
- )
- self.assertTrue(str(q3.query).count('LEFT OUTER JOIN') == 1)
- self.assertTrue(str(q3.query).count('INNER JOIN') == 0)
- def test_ticket19672(self):
- self.assertQuerysetEqual(
- Report.objects.filter(Q(creator__isnull=False) &
- ~Q(creator__extra__value=41)),
- ['<Report: r1>']
- )
- def test_ticket_20250(self):
-
- qs = Author.objects.annotate(Count('item'))
- qs = qs.filter(~Q(extra__value=0))
- self.assertTrue('SELECT' in str(qs.query))
- self.assertQuerysetEqual(
- qs,
- ['<Author: a1>', '<Author: a2>', '<Author: a3>', '<Author: a4>']
- )
- class Queries2Tests(TestCase):
- def setUp(self):
- Number.objects.create(num=4)
- Number.objects.create(num=8)
- Number.objects.create(num=12)
- def test_ticket4289(self):
-
-
- self.assertQuerysetEqual(Number.objects.filter(num__lt=4), [])
- self.assertQuerysetEqual(Number.objects.filter(num__gt=8, num__lt=12), [])
- self.assertQuerysetEqual(
- Number.objects.filter(num__gt=8, num__lt=13),
- ['<Number: 12>']
- )
- self.assertQuerysetEqual(
- Number.objects.filter(Q(num__lt=4) | Q(num__gt=8, num__lt=12)),
- []
- )
- self.assertQuerysetEqual(
- Number.objects.filter(Q(num__gt=8, num__lt=12) | Q(num__lt=4)),
- []
- )
- self.assertQuerysetEqual(
- Number.objects.filter(Q(num__gt=8) & Q(num__lt=12) | Q(num__lt=4)),
- []
- )
- self.assertQuerysetEqual(
- Number.objects.filter(Q(num__gt=7) & Q(num__lt=12) | Q(num__lt=4)),
- ['<Number: 8>']
- )
- def test_ticket12239(self):
-
-
-
- self.assertQuerysetEqual(
- Number.objects.filter(num__gt=11.9),
- ['<Number: 12>']
- )
- self.assertQuerysetEqual(Number.objects.filter(num__gt=12), [])
- self.assertQuerysetEqual(Number.objects.filter(num__gt=12.0), [])
- self.assertQuerysetEqual(Number.objects.filter(num__gt=12.1), [])
- self.assertQuerysetEqual(
- Number.objects.filter(num__lt=12),
- ['<Number: 4>', '<Number: 8>'],
- ordered=False
- )
- self.assertQuerysetEqual(
- Number.objects.filter(num__lt=12.0),
- ['<Number: 4>', '<Number: 8>'],
- ordered=False
- )
- self.assertQuerysetEqual(
- Number.objects.filter(num__lt=12.1),
- ['<Number: 4>', '<Number: 8>', '<Number: 12>'],
- ordered=False
- )
- self.assertQuerysetEqual(
- Number.objects.filter(num__gte=11.9),
- ['<Number: 12>']
- )
- self.assertQuerysetEqual(
- Number.objects.filter(num__gte=12),
- ['<Number: 12>']
- )
- self.assertQuerysetEqual(
- Number.objects.filter(num__gte=12.0),
- ['<Number: 12>']
- )
- self.assertQuerysetEqual(Number.objects.filter(num__gte=12.1), [])
- self.assertQuerysetEqual(Number.objects.filter(num__gte=12.9), [])
- self.assertQuerysetEqual(
- Number.objects.filter(num__lte=11.9),
- ['<Number: 4>', '<Number: 8>'],
- ordered=False
- )
- self.assertQuerysetEqual(
- Number.objects.filter(num__lte=12),
- ['<Number: 4>', '<Number: 8>', '<Number: 12>'],
- ordered=False
- )
- self.assertQuerysetEqual(
- Number.objects.filter(num__lte=12.0),
- ['<Number: 4>', '<Number: 8>', '<Number: 12>'],
- ordered=False
- )
- self.assertQuerysetEqual(
- Number.objects.filter(num__lte=12.1),
- ['<Number: 4>', '<Number: 8>', '<Number: 12>'],
- ordered=False
- )
- self.assertQuerysetEqual(
- Number.objects.filter(num__lte=12.9),
- ['<Number: 4>', '<Number: 8>', '<Number: 12>'],
- ordered=False
- )
- def test_ticket7759(self):
-
- count = Number.objects.count()
- qs = Number.objects.all()
- def run():
- for obj in qs:
- return qs.count() == count
- self.assertTrue(run())
- class Queries3Tests(BaseQuerysetTest):
- def test_ticket7107(self):
-
- self.assertQuerysetEqual(Valid.objects.all(), [])
- def test_ticket8683(self):
-
-
- self.assertRaisesMessage(
- AssertionError,
- "'name' isn't a DateTimeField.",
- Item.objects.datetimes, 'name', 'month'
- )
- class Queries4Tests(BaseQuerysetTest):
- def setUp(self):
- generic = NamedCategory.objects.create(name="Generic")
- self.t1 = Tag.objects.create(name='t1', category=generic)
- n1 = Note.objects.create(note='n1', misc='foo', id=1)
- n2 = Note.objects.create(note='n2', misc='bar', id=2)
- e1 = ExtraInfo.objects.create(info='e1', note=n1)
- e2 = ExtraInfo.objects.create(info='e2', note=n2)
- self.a1 = Author.objects.create(name='a1', num=1001, extra=e1)
- self.a3 = Author.objects.create(name='a3', num=3003, extra=e2)
- self.r1 = Report.objects.create(name='r1', creator=self.a1)
- self.r2 = Report.objects.create(name='r2', creator=self.a3)
- self.r3 = Report.objects.create(name='r3')
- Item.objects.create(name='i1', created=datetime.datetime.now(), note=n1, creator=self.a1)
- Item.objects.create(name='i2', created=datetime.datetime.now(), note=n1, creator=self.a3)
- def test_ticket14876(self):
-
-
-
-
- q1 = Report.objects.filter(Q(creator__isnull=True) | Q(creator__extra__info='e1'))
- q2 = Report.objects.filter(Q(creator__isnull=True)) | Report.objects.filter(Q(creator__extra__info='e1'))
- self.assertQuerysetEqual(q1, ["<Report: r1>", "<Report: r3>"], ordered=False)
- self.assertEqual(str(q1.query), str(q2.query))
- q1 = Report.objects.filter(Q(creator__extra__info='e1') | Q(creator__isnull=True))
- q2 = Report.objects.filter(Q(creator__extra__info='e1')) | Report.objects.filter(Q(creator__isnull=True))
- self.assertQuerysetEqual(q1, ["<Report: r1>", "<Report: r3>"], ordered=False)
- self.assertEqual(str(q1.query), str(q2.query))
- q1 = Item.objects.filter(Q(creator=self.a1) | Q(creator__report__name='r1')).order_by()
- q2 = Item.objects.filter(Q(creator=self.a1)).order_by() | Item.objects.filter(Q(creator__report__name='r1')).order_by()
- self.assertQuerysetEqual(q1, ["<Item: i1>"])
- self.assertEqual(str(q1.query), str(q2.query))
- q1 = Item.objects.filter(Q(creator__report__name='e1') | Q(creator=self.a1)).order_by()
- q2 = Item.objects.filter(Q(creator__report__name='e1')).order_by() | Item.objects.filter(Q(creator=self.a1)).order_by()
- self.assertQuerysetEqual(q1, ["<Item: i1>"])
- self.assertEqual(str(q1.query), str(q2.query))
- def test_combine_join_reuse(self):
-
-
-
- Report.objects.create(name='r4', creator=self.a1)
- q1 = Author.objects.filter(report__name='r5')
- q2 = Author.objects.filter(report__name='r4').filter(report__name='r1')
- combined = q1|q2
- self.assertEqual(str(combined.query).count('JOIN'), 2)
- self.assertEqual(len(combined), 1)
- self.assertEqual(combined[0].name, 'a1')
- def test_ticket7095(self):
-
-
- ManagedModel.objects.create(data='mm1', tag=self.t1, public=True)
- self.assertEqual(ManagedModel.objects.update(data='mm'), 1)
-
-
-
-
- if connection.features.interprets_empty_strings_as_nulls:
- expected_null_charfield_repr = ''
- else:
- expected_null_charfield_repr = None
- self.assertValueQuerysetEqual(
- Report.objects.values_list("creator__extra__info", flat=True).order_by("name"),
- ['e1', 'e2', expected_null_charfield_repr],
- )
-
-
- self.assertQuerysetEqual(
- Report.objects.select_related("creator", "creator__extra").order_by("name"),
- ['<Report: r1>', '<Report: r2>', '<Report: r3>']
- )
-
-
-
-
- d1 = Detail.objects.create(data="d1")
- d2 = Detail.objects.create(data="d2")
- m1 = Member.objects.create(name="m1", details=d1)
- m2 = Member.objects.create(name="m2", details=d2)
- Child.objects.create(person=m2, parent=m1)
- obj = m1.children.select_related("person__details")[0]
- self.assertEqual(obj.person.details.data, 'd2')
- def test_order_by_resetting(self):
-
-
- qs = Author.objects.order_by().order_by('name')
- self.assertTrue('ORDER BY' in qs.query.get_compiler(qs.db).as_sql()[0])
- def test_ticket10181(self):
-
-
- self.assertQuerysetEqual(
- Tag.objects.filter(id__in=Tag.objects.filter(id__in=[])),
- []
- )
- def test_ticket15316_filter_false(self):
- c1 = SimpleCategory.objects.create(name="category1")
- c2 = SpecialCategory.objects.create(name="named category1",
- special_name="special1")
- c3 = SpecialCategory.objects.create(name="named category2",
- special_name="special2")
- ci1 = CategoryItem.objects.create(category=c1)
- ci2 = CategoryItem.objects.create(category=c2)
- ci3 = CategoryItem.objects.create(category=c3)
- qs = CategoryItem.objects.filter(category__specialcategory__isnull=False)
- self.assertEqual(qs.count(), 2)
- self.assertQuerysetEqual(qs, [ci2.pk, ci3.pk], lambda x: x.pk, False)
- def test_ticket15316_exclude_false(self):
- c1 = SimpleCategory.objects.create(name="category1")
- c2 = SpecialCategory.objects.create(name="named category1",
- special_name="special1")
- c3 = SpecialCategory.objects.create(name="named category2",
- special_name="special2")
- ci1 = CategoryItem.objects.create(category=c1)
- ci2 = CategoryItem.objects.create(category=c2)
- ci3 = CategoryItem.objects.create(category=c3)
- qs = CategoryItem.objects.exclude(category__specialcategory__isnull=False)
- self.assertEqual(qs.count(), 1)
- self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
- def test_ticket15316_filter_true(self):
- c1 = SimpleCategory.objects.create(name="category1")
- c2 = SpecialCategory.objects.create(name="named category1",
- special_name="special1")
- c3 = SpecialCategory.objects.create(name="named category2",
- special_name="special2")
- ci1 = CategoryItem.objects.create(category=c1)
- ci2 = CategoryItem.objects.create(category=c2)
- ci3 = CategoryItem.objects.create(category=c3)
- qs = CategoryItem.objects.filter(category__specialcategory__isnull=True)
- self.assertEqual(qs.count(), 1)
- self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
- def test_ticket15316_exclude_true(self):
- c1 = SimpleCategory.objects.create(name="category1")
- c2 = SpecialCategory.objects.create(name="named category1",
- special_name="special1")
- c3 = SpecialCategory.objects.create(name="named category2",
- special_name="special2")
- ci1 = CategoryItem.objects.create(category=c1)
- ci2 = CategoryItem.objects.create(category=c2)
- ci3 = CategoryItem.objects.create(category=c3)
- qs = CategoryItem.objects.exclude(category__specialcategory__isnull=True)
- self.assertEqual(qs.count(), 2)
- self.assertQuerysetEqual(qs, [ci2.pk, ci3.pk], lambda x: x.pk, False)
- def test_ticket15316_one2one_filter_false(self):
- c = SimpleCategory.objects.create(name="cat")
- c0 = SimpleCategory.objects.create(name="cat0")
- c1 = SimpleCategory.objects.create(name="category1")
- c2 = OneToOneCategory.objects.create(category = c1, new_name="new1")
- c3 = OneToOneCategory.objects.create(category = c0, new_name="new2")
- ci1 = CategoryItem.objects.create(category=c)
- ci2 = CategoryItem.objects.create(category=c0)
- ci3 = CategoryItem.objects.create(category=c1)
- qs = CategoryItem.objects.filter(category__onetoonecategory__isnull=False)
- self.assertEqual(qs.count(), 2)
- self.assertQuerysetEqual(qs, [ci2.pk, ci3.pk], lambda x: x.pk, False)
- def test_ticket15316_one2one_exclude_false(self):
- c = SimpleCategory.objects.create(name="cat")
- c0 = SimpleCategory.objects.create(name="cat0")
- c1 = SimpleCategory.objects.create(name="category1")
- c2 = OneToOneCategory.objects.create(category = c1, new_name="new1")
- c3 = OneToOneCategory.objects.create(category = c0, new_name="new2")
- ci1 = CategoryItem.objects.create(category=c)
- ci2 = CategoryItem.objects.create(category=c0)
- ci3 = CategoryItem.objects.create(category=c1)
- qs = CategoryItem.objects.exclude(category__onetoonecategory__isnull=False)
- self.assertEqual(qs.count(), 1)
- self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
- def test_ticket15316_one2one_filter_true(self):
- c = SimpleCategory.objects.create(name="cat")
- c0 = SimpleCategory.objects.create(name="cat0")
- c1 = SimpleCategory.objects.create(name="category1")
- c2 = OneToOneCategory.objects.create(category = c1, new_name="new1")
- c3 = OneToOneCategory.objects.create(category = c0, new_name="new2")
- ci1 = CategoryItem.objects.create(category=c)
- ci2 = CategoryItem.objects.create(category=c0)
- ci3 = CategoryItem.objects.create(category=c1)
- qs = CategoryItem.objects.filter(category__onetoonecategory__isnull=True)
- self.assertEqual(qs.count(), 1)
- self.assertQuerysetEqual(qs, [ci1.pk], lambda x: x.pk)
- def test_ticket15316_one2one_exclude_true(self):
- c = SimpleCategory.objects.create(name="cat")
- c0 = SimpleCategory.objects.create(name="cat0")
- c1 = SimpleCategory.objects.create(name="category1")
- c2 = OneToOneCategory.objects.create(category = c1, new_name="new1")
- c3 = OneToOneCategory.objects.create(category = c0, new_name="new2")
- ci1 = CategoryItem.objects.create(category=c)
- ci2 = CategoryItem.objects.create(category=c0)
- ci3 = CategoryItem.objects.create(category=c1)
- qs = CategoryItem.objects.exclude(category__onetoonecategory__isnull=True)
- self.assertEqual(qs.count(), 2)
- self.assertQuerysetEqual(qs, [ci2.pk, ci3.pk], lambda x: x.pk, False)
- class Queries5Tests(TestCase):
- def setUp(self):
-
-
- n1 = Note.objects.create(note='n1', misc='foo', id=1)
- n2 = Note.objects.create(note='n2', misc='bar', id=2)
- e1 = ExtraInfo.objects.create(info='e1', note=n1)
- e2 = ExtraInfo.objects.create(info='e2', note=n2)
- a1 = Author.objects.create(name='a1', num=1001, extra=e1)
- a2 = Author.objects.create(name='a2', num=2002, extra=e1)
- a3 = Author.objects.create(name='a3', num=3003, extra=e2)
- self.rank1 = Ranking.objects.create(rank=2, author=a2)
- Ranking.objects.create(rank=1, author=a3)
- Ranking.objects.create(rank=3, author=a1)
- def test_ordering(self):
-
- self.assertQuerysetEqual(
- Ranking.objects.all(),
- ['<Ranking: 3: a1>', '<Ranking: 2: a2>', '<Ranking: 1: a3>']
- )
- self.assertQuerysetEqual(
- Ranking.objects.all().order_by('rank'),
- ['<Ranking: 1: a3>', '<Ranking: 2: a2>', '<Ranking: 3: a1>']
- )
-
-
- self.assertQuerysetEqual(
- Ranking.objects.extra(tables=['django_site'], order_by=['-django_site.id', 'rank']),
- ['<Ranking: 1: a3>', '<Ranking: 2: a2>', '<Ranking: 3: a1>']
- )
- qs = Ranking.objects.extra(select={'good': 'case when rank > 2 then 1 else 0 end'})
- self.assertEqual(
- [o.good for o in qs.extra(order_by=('-good',))],
- [True, False, False]
- )
- self.assertQuerysetEqual(
- qs.extra(order_by=('-good', 'id')),
- ['<Ranking: 3: a1>', '<Ranking: 2: a2>', '<Ranking: 1: a3>']
- )
-
-
- dicts = qs.values('id', 'rank').order_by('id')
- self.assertEqual(
- [d['rank'] for d in dicts],
- [2, 1, 3]
- )
- def test_ticket7256(self):
-
-
- qs = Ranking.objects.extra(select={'good': 'case when rank > 2 then 1 else 0 end'})
- dicts = qs.values().order_by('id')
- for d in dicts: del d['id']; del d['author_id']
- self.assertEqual(
- [sorted(d.items()) for d in dicts],
- [[('good', 0), ('rank', 2)], [('good', 0), ('rank', 1)], [('good', 1), ('rank', 3)]]
- )
- def test_ticket7045(self):
-
- qs = Ranking.objects.extra(tables=['django_site'])
- qs.query.get_compiler(qs.db).as_sql()
-
- qs.query.get_compiler(qs.db).as_sql()
- def test_ticket9848(self):
-
-
-
- self.assertQuerysetEqual(
- Ranking.objects.filter(author__name='a1'),
- ['<Ranking: 3: a1>']
- )
- self.assertEqual(
- Ranking.objects.filter(author__name='a1').update(rank='4'),
- 1
- )
- r = Ranking.objects.filter(author__name='a1')[0]
- self.assertNotEqual(r.id, r.author.id)
- self.assertEqual(r.rank, 4)
- r.rank = 3
- r.save()
- self.assertQuerysetEqual(
- Ranking.objects.all(),
- ['<Ranking: 3: a1>', '<Ranking: 2: a2>', '<Ranking: 1: a3>']
- )
- def test_ticket5261(self):
-
- self.assertQuerysetEqual(
- Note.objects.exclude(Q()),
- ['<Note: n1>', '<Note: n2>']
- )
- self.assertQuerysetEqual(
- Note.objects.filter(~Q()),
- ['<Note: n1>', '<Note: n2>']
- )
- self.assertQuerysetEqual(
- Note.objects.filter(~Q()|~Q()),
- ['<Note: n1>', '<Note: n2>']
- )
- self.assertQuerysetEqual(
- Note.objects.exclude(~Q()&~Q()),
- ['<Note: n1>', '<Note: n2>']
- )
- class SelectRelatedTests(TestCase):
- def test_tickets_3045_3288(self):
-
-
-
- self.assertQuerysetEqual(X.objects.all(), [])
- self.assertQuerysetEqual(X.objects.select_related(), [])
- class SubclassFKTests(TestCase):
- def test_ticket7778(self):
-
-
- num_celebs = Celebrity.objects.count()
- tvc = TvChef.objects.create(name="Huey")
- self.assertEqual(Celebrity.objects.count(), num_celebs + 1)
- Fan.objects.create(fan_of=tvc)
- Fan.objects.create(fan_of=tvc)
- tvc.delete()
-
- self.assertEqual(Celebrity.objects.count(), num_celebs)
- class CustomPkTests(TestCase):
- def test_ticket7371(self):
- self.assertQuerysetEqual(Related.objects.order_by('custom'), [])
- class NullableRelOrderingTests(TestCase):
- def test_ticket10028(self):
-
-
- Plaything.objects.create(name="p1")
- self.assertQuerysetEqual(
- Plaything.objects.all(),
- ['<Plaything: p1>']
- )
- def test_join_already_in_query(self):
-
-
- Plaything.objects.create(name="p1")
- s = SingleObject.objects.create(name='s')
- r = RelatedObject.objects.create(single=s, f=1)
- Plaything.objects.create(name="p2", others=r)
- qs = Plaything.objects.all().filter(others__isnull=False).order_by('pk')
- self.assertTrue('JOIN' not in str(qs.query))
- qs = Plaything.objects.all().filter(others__f__isnull=False).order_by('pk')
- self.assertTrue('INNER' in str(qs.query))
- qs = qs.order_by('others__single__name')
-
-
-
-
- self.assertEqual(str(qs.query).count('LEFT'), 1)
- self.assertEqual(str(qs.query).count('INNER'), 1)
- self.assertQuerysetEqual(
- qs,
- ['<Plaything: p2>']
- )
- class DisjunctiveFilterTests(TestCase):
- def setUp(self):
- self.n1 = Note.objects.create(note='n1', misc='foo', id=1)
- ExtraInfo.objects.create(info='e1', note=self.n1)
- def test_ticket7872(self):
-
-
-
- LeafA.objects.create(data='first')
- self.assertQuerysetEqual(LeafA.objects.all(), ['<LeafA: first>'])
- self.assertQuerysetEqual(
- LeafA.objects.filter(Q(data='first')|Q(join__b__data='second')),
- ['<LeafA: first>']
- )
- def test_ticket8283(self):
-
- self.assertQuerysetEqual(
- (ExtraInfo.objects.filter(note=self.n1)|ExtraInfo.objects.filter(info='e2')).filter(note=self.n1),
- ['<ExtraInfo: e1>']
- )
- self.assertQuerysetEqual(
- (ExtraInfo.objects.filter(info='e2')|ExtraInfo.objects.filter(note=self.n1)).filter(note=self.n1),
- ['<ExtraInfo: e1>']
- )
- class Queries6Tests(TestCase):
- def setUp(self):
- generic = NamedCategory.objects.create(name="Generic")
- t1 = Tag.objects.create(name='t1', category=generic)
- t2 = Tag.objects.create(name='t2', parent=t1, category=generic)
- t3 = Tag.objects.create(name='t3', parent=t1)
- t4 = Tag.objects.create(name='t4', parent=t3)
- t5 = Tag.objects.create(name='t5', parent=t3)
- n1 = Note.objects.create(note='n1', misc='foo', id=1)
- ann1 = Annotation.objects.create(name='a1', tag=t1)
- ann1.notes.add(n1)
- ann2 = Annotation.objects.create(name='a2', tag=t4)
- def test_parallel_iterators(self):
-
- qs = Tag.objects.all()
- i1, i2 = iter(qs), iter(qs)
- self.assertEqual(repr(next(i1)), '<Tag: t1>')
- self.assertEqual(repr(next(i1)), '<Tag: t2>')
- self.assertEqual(repr(next(i2)), '<Tag: t1>')
- self.assertEqual(repr(next(i2)), '<Tag: t2>')
- self.assertEqual(repr(next(i2)), '<Tag: t3>')
- self.assertEqual(repr(next(i1)), '<Tag: t3>')
- qs = X.objects.all()
- self.assertEqual(bool(qs), False)
- self.assertEqual(bool(qs), False)
- def test_nested_queries_sql(self):
-
-
- qs = Annotation.objects.filter(notes__in=Note.objects.filter(note="xyzzy"))
- self.assertEqual(
- qs.query.get_compiler(qs.db).as_sql()[0].count('SELECT'),
- 2
- )
- def test_tickets_8921_9188(self):
-
-
-
- self.assertQuerysetEqual(
- PointerA.objects.filter(connection__pointerb__id=1),
- []
- )
- self.assertQuerysetEqual(
- PointerA.objects.exclude(connection__pointerb__id=1),
- []
- )
- self.assertQuerysetEqual(
- Tag.objects.exclude(children=None),
- ['<Tag: t1>', '<Tag: t3>']
- )
-
-
- self.assertQuerysetEqual(
- Tag.objects.exclude(parent__annotation__name="a1"),
- ['<Tag: t1>', '<Tag: t4>', '<Tag: t5>']
- )
-
-
-
- self.assertQuerysetEqual(
- Annotation.objects.exclude(tag__children__name="t2"),
- ['<Annotation: a2>']
- )
-
-
- self.assertQuerysetEqual(
- Annotation.objects.filter(notes__in=Note.objects.filter(note="n1")),
- ['<Annotation: a1>']
- )
- def test_ticket3739(self):
-
- q1 = Tag.objects.order_by('name')
- self.assertIsNot(q1, q1.all())
- class RawQueriesTests(TestCase):
- def setUp(self):
- n1 = Note.objects.create(note='n1', misc='foo', id=1)
- def test_ticket14729(self):
-
- query = "SELECT * FROM queries_note WHERE note = %s"
- params = ['n1']
- qs = Note.objects.raw(query, params=params)
- self.assertEqual(repr(qs), str_prefix("<RawQuerySet: %(_)s'SELECT * FROM queries_note WHERE note = n1'>"))
- query = "SELECT * FROM queries_note WHERE note = %s and misc = %s"
- params = ['n1', 'foo']
- qs = Note.objects.raw(query, params=params)
- self.assertEqual(repr(qs), str_prefix("<RawQuerySet: %(_)s'SELECT * FROM queries_note WHERE note = n1 and misc = foo'>"))
- class GeneratorExpressionTests(TestCase):
- def test_ticket10432(self):
-
-
- self.assertQuerysetEqual(
- Note.objects.filter(pk__in=(x for x in ())),
- []
- )
- class ComparisonTests(TestCase):
- def setUp(self):
- self.n1 = Note.objects.create(note='n1', misc='foo', id=1)
- e1 = ExtraInfo.objects.create(info='e1', note=self.n1)
- self.a2 = Author.objects.create(name='a2', num=2002, extra=e1)
- def test_ticket8597(self):
-
- _ = Item.objects.create(name="a_b", created=datetime.datetime.now(), creator=self.a2, note=self.n1)
- _ = Item.objects.create(name="x%y", created=datetime.datetime.now(), creator=self.a2, note=self.n1)
- self.assertQuerysetEqual(
- Item.objects.filter(name__iexact="A_b"),
- ['<Item: a_b>']
- )
- self.assertQuerysetEqual(
- Item.objects.filter(name__iexact="x%Y"),
- ['<Item: x%y>']
- )
- self.assertQuerysetEqual(
- Item.objects.filter(name__istartswith="A_b"),
- ['<Item: a_b>']
- )
- self.assertQuerysetEqual(
- Item.objects.filter(name__iendswith="A_b"),
- ['<Item: a_b>']
- )
- class ExistsSql(TestCase):
- def setUp(self):
- settings.DEBUG = True
- def test_exists(self):
- self.assertFalse(Tag.objects.exists())
-
- self.assertTrue("id" not in connection.queries[-1]['sql'] and "name" not in connection.queries[-1]['sql'])
- def tearDown(self):
- settings.DEBUG = False
- class QuerysetOrderedTests(unittest.TestCase):
- """
- Tests for the Queryset.ordered attribute.
- """
- def test_no_default_or_explicit_ordering(self):
- self.assertEqual(Annotation.objects.all().ordered, False)
- def test_cleared_default_ordering(self):
- self.assertEqual(Tag.objects.all().ordered, True)
- self.assertEqual(Tag.objects.all().order_by().ordered, False)
- def test_explicit_ordering(self):
- self.assertEqual(Annotation.objects.all().order_by('id').ordered, True)
- def test_order_by_extra(self):
- self.assertEqual(Annotation.objects.all().extra(order_by=['id']).ordered, True)
- def test_annotated_ordering(self):
- qs = Annotation.objects.annotate(num_notes=Count('notes'))
- self.assertEqual(qs.ordered, False)
- self.assertEqual(qs.order_by('num_notes').ordered, True)
- class SubqueryTests(TestCase):
- def setUp(self):
- DumbCategory.objects.create(id=1)
- DumbCategory.objects.create(id=2)
- DumbCategory.objects.create(id=3)
- def test_ordered_subselect(self):
- "Subselects honor any manual ordering"
- try:
- query = DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[0:2])
- self.assertEqual(set(query.values_list('id', flat=True)), set([2,3]))
- query = DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[:2])
- self.assertEqual(set(query.values_list('id', flat=True)), set([2,3]))
- query = DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[2:])
- self.assertEqual(set(query.values_list('id', flat=True)), set([1]))
- except DatabaseError:
-
-
-
- self.assertFalse(connections[DEFAULT_DB_ALIAS].features.allow_sliced_subqueries)
- def test_sliced_delete(self):
- "Delete queries can safely contain sliced subqueries"
- try:
- DumbCategory.objects.filter(id__in=DumbCategory.objects.order_by('-id')[0:1]).delete()
- self.assertEqual(set(DumbCategory.objects.values_list('id', flat=True)), set([1,2]))
- except DatabaseError:
-
-
-
- self.assertFalse(connections[DEFAULT_DB_ALIAS].features.allow_sliced_subqueries)
- class CloneTests(TestCase):
- def test_evaluated_queryset_as_argument(self):
- "#13227 -- If a queryset is already evaluated, it can still be used as a query arg"
- n = Note(note='Test1', misc='misc')
- n.save()
- e = ExtraInfo(info='good', note=n)
- e.save()
- n_list = Note.objects.all()
-
- list(n_list)
-
-
- self.assertEqual(ExtraInfo.objects.filter(note__in=n_list)[0].info, 'good')
- def test_no_model_options_cloning(self):
- """
- Test that cloning a queryset does not get out of hand. While complete
- testing is impossible, this is a sanity check against invalid use of
- deepcopy. refs #16759.
- """
- opts_class = type(Note._meta)
- note_deepcopy = getattr(opts_class, "__deepcopy__", None)
- opts_class.__deepcopy__ = lambda obj, memo: self.fail("Model options shouldn't be cloned.")
- try:
- Note.objects.filter(pk__lte=F('pk') + 1).all()
- finally:
- if note_deepcopy is None:
- delattr(opts_class, "__deepcopy__")
- else:
- opts_class.__deepcopy__ = note_deepcopy
- def test_no_fields_cloning(self):
- """
- Test that cloning a queryset does not get out of hand. While complete
- testing is impossible, this is a sanity check against invalid use of
- deepcopy. refs #16759.
- """
- opts_class = type(Note._meta.get_field_by_name("misc")[0])
- note_deepcopy = getattr(opts_class, "__deepcopy__", None)
- opts_class.__deepcopy__ = lambda obj, memo: self.fail("Model fields shouldn't be cloned")
- try:
- Note.objects.filter(note=F('misc')).all()
- finally:
- if note_deepcopy is None:
- delattr(opts_class, "__deepcopy__")
- else:
- opts_class.__deepcopy__ = note_deepcopy
- class EmptyQuerySetTests(TestCase):
- def test_emptyqueryset_values(self):
-
-
- self.assertQuerysetEqual(
- Number.objects.none().values('num').order_by('num'), []
- )
- def test_values_subquery(self):
- self.assertQuerysetEqual(
- Number.objects.filter(pk__in=Number.objects.none().values("pk")),
- []
- )
- self.assertQuerysetEqual(
- Number.objects.filter(pk__in=Number.objects.none().values_list("pk")),
- []
- )
- def test_ticket_19151(self):
-
-
- q = Author.objects.none()
- self.assertQuerysetEqual(q.values(), [])
- self.assertQuerysetEqual(q.values_list(), [])
- class ValuesQuerysetTests(BaseQuerysetTest):
- def setUp(self):
- Number.objects.create(num=72)
- self.identity = lambda x: x
- def test_flat_values_list(self):
- qs = Number.objects.values_list("num")
- qs = qs.values_list("num", flat=True)
- self.assertValueQuerysetEqual(qs, [72])
- def test_extra_values(self):
-
- qs = Number.objects.extra(select=SortedDict([('value_plus_x', 'num+%s'),
- ('value_minus_x', 'num-%s')]),
- select_params=(1, 2))
- qs = qs.order_by('value_minus_x')
- qs = qs.values('num')
- self.assertQuerysetEqual(qs, [{'num': 72}], self.identity)
- def test_extra_values_order_twice(self):
-
- qs = Number.objects.extra(select={'value_plus_one': 'num+1', 'value_minus_one': 'num-1'})
- qs = qs.order_by('value_minus_one').order_by('value_plus_one')
- qs = qs.values('num')
- self.assertQuerysetEqual(qs, [{'num': 72}], self.identity)
- def test_extra_values_order_multiple(self):
-
- qs = Number.objects.extra(select={
- 'value_plus_one': 'num+1',
- 'value_minus_one': 'num-1',
- 'constant_value': '1'
- })
- qs = qs.order_by('value_plus_one', 'value_minus_one', 'constant_value')
- qs = qs.values('num')
- self.assertQuerysetEqual(qs, [{'num': 72}], self.identity)
- def test_extra_values_order_in_extra(self):
-
- qs = Number.objects.extra(
- select={'value_plus_one': 'num+1', 'value_minus_one': 'num-1'},
- order_by=['value_minus_one'])
- qs = qs.values('num')
- def test_extra_values_list(self):
-
- qs = Number.objects.extra(select={'value_plus_one': 'num+1'})
- qs = qs.order_by('value_plus_one')
- qs = qs.values_list('num')
- self.assertQuerysetEqual(qs, [(72,)], self.identity)
- def test_flat_extra_values_list(self):
-
- qs = Number.objects.extra(select={'value_plus_one': 'num+1'})
- qs = qs.order_by('value_plus_one')
- qs = qs.values_list('num', flat=True)
- self.assertQuerysetEqual(qs, [72], self.identity)
- class WeirdQuerysetSlicingTests(BaseQuerysetTest):
- def setUp(self):
- Number.objects.create(num=1)
- Number.objects.create(num=2)
- Article.objects.create(name='one', created=datetime.datetime.now())
- Article.objects.create(name='two', created=datetime.datetime.now())
- Article.objects.create(name='three', created=datetime.datetime.now())
- Article.objects.create(name='four', created=datetime.datetime.now())
- def test_tickets_7698_10202(self):
-
- self.assertQuerysetEqual(Article.objects.all()[0:0], [])
- self.assertQuerysetEqual(Article.objects.all()[0:0][:10], [])
- self.assertEqual(Article.objects.all()[:0].count(), 0)
- self.assertRaisesMessage(
- AssertionError,
- 'Cannot change a query once a slice has been taken.',
- Article.objects.all()[:0].latest, 'created'
- )
- def test_empty_resultset_sql(self):
-
- self.assertNumQueries(0, lambda: list(Number.objects.all()[1:1]))
- class EscapingTests(TestCase):
- def test_ticket_7302(self):
-
- _ = ReservedName.objects.create(name='a', order=42)
- ReservedName.objects.create(name='b', order=37)
- self.assertQuerysetEqual(
- ReservedName.objects.all().order_by('order'),
- ['<ReservedName: b>', '<ReservedName: a>']
- )
- self.assertQuerysetEqual(
- ReservedName.objects.extra(select={'stuff':'name'}, order_by=('order','stuff')),
- ['<ReservedName: b>', '<ReservedName: a>']
- )
- class ToFieldTests(TestCase):
- def test_in_query(self):
- apple = Food.objects.create(name="apple")
- pear = Food.objects.create(name="pear")
- lunch = Eaten.objects.create(food=apple, meal="lunch")
- dinner = Eaten.objects.create(food=pear, meal="dinner")
- self.assertEqual(
- set(Eaten.objects.filter(food__in=[apple, pear])),
- set([lunch, dinner]),
- )
- def test_reverse_in(self):
- apple = Food.objects.create(name="apple")
- pear = Food.objects.create(name="pear")
- lunch_apple = Eaten.objects.create(food=apple, meal="lunch")
- lunch_pear = Eaten.objects.create(food=pear, meal="dinner")
- self.assertEqual(
- set(Food.objects.filter(eaten__in=[lunch_apple, lunch_pear])),
- set([apple, pear])
- )
- def test_single_object(self):
- apple = Food.objects.create(name="apple")
- lunch = Eaten.objects.create(food=apple, meal="lunch")
- dinner = Eaten.objects.create(food=apple, meal="dinner")
- self.assertEqual(
- set(Eaten.objects.filter(food=apple)),
- set([lunch, dinner])
- )
- def test_single_object_reverse(self):
- apple = Food.objects.create(name="apple")
- lunch = Eaten.objects.create(food=apple, meal="lunch")
- self.assertEqual(
- set(Food.objects.filter(eaten=lunch)),
- set([apple])
- )
- def test_recursive_fk(self):
- node1 = Node.objects.create(num=42)
- node2 = Node.objects.create(num=1, parent=node1)
- self.assertEqual(
- list(Node.objects.filter(parent=node1)),
- [node2]
- )
- def test_recursive_fk_reverse(self):
- node1 = Node.objects.create(num=42)
- node2 = Node.objects.create(num=1, parent=node1)
- self.assertEqual(
- list(Node.objects.filter(node=node2)),
- [node1]
- )
- class ConditionalTests(BaseQuerysetTest):
- """Tests whose execution depend on different environment conditions like
- Python version or DB backend features"""
- def setUp(self):
- generic = NamedCategory.objects.create(name="Generic")
- t1 = Tag.objects.create(name='t1', category=generic)
- t2 = Tag.objects.create(name='t2', parent=t1, category=generic)
- t3 = Tag.objects.create(name='t3', parent=t1)
- t4 = Tag.objects.create(name='t4', parent=t3)
- t5 = Tag.objects.create(name='t5', parent=t3)
-
-
-
-
-
- @unittest.skipIf(sys.version_info[:2] == (2, 6), "Python version is 2.6")
- def test_infinite_loop(self):
-
-
- self.assertRaisesMessage(
- FieldError,
- 'Infinite loop caused by ordering.',
- lambda: list(LoopX.objects.all())
- )
- self.assertRaisesMessage(
- FieldError,
- 'Infinite loop caused by ordering.',
- lambda: list(LoopZ.objects.all())
- )
-
-
-
- self.assertEqual(len(Tag.objects.order_by('parent')), 5)
-
-
-
- self.assertQuerysetEqual(
- LoopX.objects.all().order_by('y__x__y__x__id'),
- []
- )
-
-
- @skipUnlessDBFeature('requires_explicit_null_ordering_when_grouping')
- def test_null_ordering_added(self):
- query = Tag.objects.values_list('parent_id', flat=True).order_by().query
- query.group_by = ['parent_id']
- sql = query.get_compiler(DEFAULT_DB_ALIAS).as_sql()[0]
- fragment = "ORDER BY "
- pos = sql.find(fragment)
- self.assertEqual(sql.find(fragment, pos + 1), -1)
- self.assertEqual(sql.find("NULL", pos + len(fragment)), pos + len(fragment))
-
-
- @skipUnlessDBFeature('supports_1000_query_parameters')
- def test_ticket14244(self):
-
-
-
- numbers = range(2050)
- Number.objects.all().delete()
- Number.objects.bulk_create(Number(num=num) for num in numbers)
- self.assertEqual(
- Number.objects.filter(num__in=numbers[:1000]).count(),
- 1000
- )
- self.assertEqual(
- Number.objects.filter(num__in=numbers[:1001]).count(),
- 1001
- )
- self.assertEqual(
- Number.objects.filter(num__in=numbers[:2000]).count(),
- 2000
- )
- self.assertEqual(
- Number.objects.filter(num__in=numbers).count(),
- len(numbers)
- )
- class UnionTests(unittest.TestCase):
- """
- Tests for the union of two querysets. Bug #12252.
- """
- def setUp(self):
- objectas = []
- objectbs = []
- objectcs = []
- a_info = ['one', 'two', 'three']
- for name in a_info:
- o = ObjectA(name=name)
- o.save()
- objectas.append(o)
- b_info = [('un', 1, objectas[0]), ('deux', 2, objectas[0]), ('trois', 3, objectas[2])]
- for name, number, objecta in b_info:
- o = ObjectB(name=name, num=number, objecta=objecta)
- o.save()
- objectbs.append(o)
- c_info = [('ein', objectas[2], objectbs[2]), ('zwei', objectas[1], objectbs[1])]
- for name, objecta, objectb in c_info:
- o = ObjectC(name=name, objecta=objecta, objectb=objectb)
- o.save()
- objectcs.append(o)
- def check_union(self, model, Q1, Q2):
- filter = model.objects.filter
- self.assertEqual(set(filter(Q1) | filter(Q2)), set(filter(Q1 | Q2)))
- self.assertEqual(set(filter(Q2) | filter(Q1)), set(filter(Q1 | Q2)))
- def test_A_AB(self):
- Q1 = Q(name='two')
- Q2 = Q(objectb__name='deux')
- self.check_union(ObjectA, Q1, Q2)
- def test_A_AB2(self):
- Q1 = Q(name='two')
- Q2 = Q(objectb__name='deux', objectb__num=2)
- self.check_union(ObjectA, Q1, Q2)
- def test_AB_ACB(self):
- Q1 = Q(objectb__name='deux')
- Q2 = Q(objectc__objectb__name='deux')
- self.check_union(ObjectA, Q1, Q2)
- def test_BAB_BAC(self):
- Q1 = Q(objecta__objectb__name='deux')
- Q2 = Q(objecta__objectc__name='ein')
- self.check_union(ObjectB, Q1, Q2)
- def test_BAB_BACB(self):
- Q1 = Q(objecta__objectb__name='deux')
- Q2 = Q(objecta__objectc__objectb__name='trois')
- self.check_union(ObjectB, Q1, Q2)
- def test_BA_BCA__BAB_BAC_BCA(self):
- Q1 = Q(objecta__name='one', objectc__objecta__name='two')
- Q2 = Q(objecta__objectc__name='ein', objectc__objecta__name='three', objecta__objectb__name='trois')
- self.check_union(ObjectB, Q1, Q2)
- class DefaultValuesInsertTest(TestCase):
- def test_no_extra_params(self):
-
- try:
- DumbCategory.objects.create()
- except TypeError:
- self.fail("Creation of an instance of a model with only the PK field shouldn't error out after bulk insert refactoring (#17056)")
- class ExcludeTest(TestCase):
- def setUp(self):
- f1 = Food.objects.create(name='apples')
- Food.objects.create(name='oranges')
- Eaten.objects.create(food=f1, meal='dinner')
- j1 = Job.objects.create(name='Manager')
- r1 = Responsibility.objects.create(description='Playing golf')
- j2 = Job.objects.create(name='Programmer')
- r2 = Responsibility.objects.create(description='Programming')
- JobResponsibilities.objects.create(job=j1, responsibility=r1)
- JobResponsibilities.objects.create(job=j2, responsibility=r2)
- def test_to_field(self):
- self.assertQuerysetEqual(
- Food.objects.exclude(eaten__meal='dinner'),
- ['<Food: oranges>'])
- self.assertQuerysetEqual(
- Job.objects.exclude(responsibilities__description='Playing golf'),
- ['<Job: Programmer>'])
- self.assertQuerysetEqual(
- Responsibility.objects.exclude(jobs__name='Manager'),
- ['<Responsibility: Programming>'])
- class ExcludeTest17600(TestCase):
- """
- Some regressiontests for ticket #17600. Some of these likely duplicate
- other existing tests.
- """
- def setUp(self):
-
- self.o1 = Order.objects.create(pk=1)
- self.o2 = Order.objects.create(pk=2)
- self.o3 = Order.objects.create(pk=3)
-
-
- self.oi1 = OrderItem.objects.create(order=self.o1, status=1)
- self.oi2 = OrderItem.objects.create(order=self.o1, status=1)
- self.oi3 = OrderItem.objects.create(order=self.o1, status=1)
-
-
- self.oi4 = OrderItem.objects.create(order=self.o2, status=1)
- self.oi5 = OrderItem.objects.create(order=self.o2, status=2)
- self.oi6 = OrderItem.objects.create(order=self.o2, status=3)
-
-
- self.oi7 = OrderItem.objects.create(order=self.o3, status=2)
- self.oi8 = OrderItem.objects.create(order=self.o3, status=3)
- self.oi9 = OrderItem.objects.create(order=self.o3, status=4)
- def test_exclude_plain(self):
- """
- This should exclude Orders which have some items with status 1
- """
- self.assertQuerysetEqual(
- Order.objects.exclude(items__status=1),
- ['<Order: 3>'])
- def test_exclude_plain_distinct(self):
- """
- This should exclude Orders which have some items with status 1
- """
- self.assertQuerysetEqual(
- Order.objects.exclude(items__status=1).distinct(),
- ['<Order: 3>'])
- def test_exclude_with_q_object_distinct(self):
- """
- This should exclude Orders which have some items with status 1
- """
- self.assertQuerysetEqual(
- Order.objects.exclude(Q(items__status=1)).distinct(),
- ['<Order: 3>'])
- def test_exclude_with_q_object_no_distinct(self):
- """
- This should exclude Orders which have some items with status 1
- """
- self.assertQuerysetEqual(
- Order.objects.exclude(Q(items__status=1)),
- ['<Order: 3>'])
- def test_exclude_with_q_is_equal_to_plain_exclude(self):
- """
- Using exclude(condition) and exclude(Q(condition)) should
- yield the same QuerySet
- """
- self.assertEqual(
- list(Order.objects.exclude(items__status=1).distinct()),
- list(Order.objects.exclude(Q(items__status=1)).distinct()))
- def test_exclude_with_q_is_equal_to_plain_exclude_variation(self):
- """
- Using exclude(condition) and exclude(Q(condition)) should
- yield the same QuerySet
- """
- self.assertEqual(
- list(Order.objects.exclude(items__status=1)),
- list(Order.objects.exclude(Q(items__status=1)).distinct()))
- @unittest.expectedFailure
- def test_only_orders_with_all_items_having_status_1(self):
- """
- This should only return orders having ALL items set to status 1, or
- those items not having any orders at all. The correct way to write
- this query in SQL seems to be using two nested subqueries.
- """
- self.assertQuerysetEqual(
- Order.objects.exclude(~Q(items__status=1)).distinct(),
- ['<Order: 1>'])
- class NullInExcludeTest(TestCase):
- def setUp(self):
- NullableName.objects.create(name='i1')
- NullableName.objects.create()
- def test_null_in_exclude_qs(self):
- none_val = '' if connection.features.interprets_empty_strings_as_nulls else None
- self.assertQuerysetEqual(
- NullableName.objects.exclude(name__in=[]),
- ['i1', none_val], attrgetter('name'))
- self.assertQuerysetEqual(
- NullableName.objects.exclude(name__in=['i1']),
- [none_val], attrgetter('name'))
- self.assertQuerysetEqual(
- NullableName.objects.exclude(name__in=['i3']),
- ['i1', none_val], attrgetter('name'))
- inner_qs = NullableName.objects.filter(name='i1').values_list('name')
- self.assertQuerysetEqual(
- NullableName.objects.exclude(name__in=inner_qs),
- [none_val], attrgetter('name'))
-
-
- self.assertIs(inner_qs._result_cache, None)
- @unittest.expectedFailure
- def test_col_not_in_list_containing_null(self):
- """
- The following case is not handled properly because
- SQL's COL NOT IN (list containing null) handling is too weird to
- abstract away.
- """
- self.assertQuerysetEqual(
- NullableName.objects.exclude(name__in=[None]),
- ['i1'], attrgetter('name'))
- def test_double_exclude(self):
- self.assertEqual(
- list(NullableName.objects.filter(~~Q(name='i1'))),
- list(NullableName.objects.filter(Q(name='i1'))))
- self.assertNotIn(
- 'IS NOT NULL',
- str(NullableName.objects.filter(~~Q(name='i1')).query))
- class EmptyStringsAsNullTest(TestCase):
- """
- Test that filtering on non-null character fields works as expected.
- The reason for these tests is that Oracle treats '' as NULL, and this
- can cause problems in query construction. Refs #17957.
- """
- def setUp(self):
- self.nc = NamedCategory.objects.create(name='')
- def test_direct_exclude(self):
- self.assertQuerysetEqual(
- NamedCategory.objects.exclude(name__in=['nonexisting']),
- [self.nc.pk], attrgetter('pk')
- )
- def test_joined_exclude(self):
- self.assertQuerysetEqual(
- DumbCategory.objects.exclude(namedcategory__name__in=['nonexisting']),
- [self.nc.pk], attrgetter('pk')
- )
- class ProxyQueryCleanupTest(TestCase):
- def test_evaluated_proxy_count(self):
- """
- Test that generating the query string doesn't alter the query's state
- in irreversible ways. Refs #18248.
- """
- ProxyCategory.objects.create()
- qs = ProxyCategory.objects.all()
- self.assertEqual(qs.count(), 1)
- str(qs.query)
- self.assertEqual(qs.count(), 1)
- class WhereNodeTest(TestCase):
- class DummyNode(object):
- def as_sql(self, qn, connection):
- return 'dummy', []
- def test_empty_full_handling_conjunction(self):
- qn = connection.ops.quote_name
- w = WhereNode(children=[EverythingNode()])
- self.assertEqual(w.as_sql(qn, connection), ('', []))
- w.negate()
- self.assertRaises(EmptyResultSet, w.as_sql, qn, connection)
- w = WhereNode(children=[NothingNode()])
- self.assertRaises(EmptyResultSet, w.as_sql, qn, connection)
- w.negate()
- self.assertEqual(w.as_sql(qn, connection), ('', []))
- w = WhereNode(children=[EverythingNode(), EverythingNode()])
- self.assertEqual(w.as_sql(qn, connection), ('', []))
- w.negate()
- self.assertRaises(EmptyResultSet, w.as_sql, qn, connection)
- w = WhereNode(children=[EverythingNode(), self.DummyNode()])
- self.assertEqual(w.as_sql(qn, connection), ('dummy', []))
- w = WhereNode(children=[self.DummyNode(), self.DummyNode()])
- self.assertEqual(w.as_sql(qn, connection), ('(dummy AND dummy)', []))
- w.negate()
- self.assertEqual(w.as_sql(qn, connection), ('NOT (dummy AND dummy)', []))
- w = WhereNode(children=[NothingNode(), self.DummyNode()])
- self.assertRaises(EmptyResultSet, w.as_sql, qn, connection)
- w.negate()
- self.assertEqual(w.as_sql(qn, connection), ('', []))
- def test_empty_full_handling_disjunction(self):
- qn = connection.ops.quote_name
- w = WhereNode(children=[EverythingNode()], connector='OR')
- self.assertEqual(w.as_sql(qn, connection), ('', []))
- w.negate()
- self.assertRaises(EmptyResultSet, w.as_sql, qn, connection)
- w = WhereNode(children=[NothingNode()], connector='OR')
- self.assertRaises(EmptyResultSet, w.as_sql, qn, connection)
- w.negate()
- self.assertEqual(w.as_sql(qn, connection), ('', []))
- w = WhereNode(children=[EverythingNode(), EverythingNode()], connector='OR')
- self.assertEqual(w.as_sql(qn, connection), ('', []))
- w.negate()
- self.assertRaises(EmptyResultSet, w.as_sql, qn, connection)
- w = WhereNode(children=[EverythingNode(), self.DummyNode()], connector='OR')
- self.assertEqual(w.as_sql(qn, connection), ('', []))
- w.negate()
- self.assertRaises(EmptyResultSet, w.as_sql, qn, connection)
- w = WhereNode(children=[self.DummyNode(), self.DummyNode()], connector='OR')
- self.assertEqual(w.as_sql(qn, connection), ('(dummy OR dummy)', []))
- w.negate()
- self.assertEqual(w.as_sql(qn, connection), ('NOT (dummy OR dummy)', []))
- w = WhereNode(children=[NothingNode(), self.DummyNode()], connector='OR')
- self.assertEqual(w.as_sql(qn, connection), ('dummy', []))
- w.negate()
- self.assertEqual(w.as_sql(qn, connection), ('NOT (dummy)', []))
- def test_empty_nodes(self):
- qn = connection.ops.quote_name
- empty_w = WhereNode()
- w = WhereNode(children=[empty_w, empty_w])
- self.assertEqual(w.as_sql(qn, connection), (None, []))
- w.negate()
- self.assertEqual(w.as_sql(qn, connection), (None, []))
- w.connector = 'OR'
- self.assertEqual(w.as_sql(qn, connection), (None, []))
- w.negate()
- self.assertEqual(w.as_sql(qn, connection), (None, []))
- w = WhereNode(children=[empty_w, NothingNode()], connector='OR')
- self.assertRaises(EmptyResultSet, w.as_sql, qn, connection)
- class IteratorExceptionsTest(TestCase):
- def test_iter_exceptions(self):
- qs = ExtraInfo.objects.only('author')
- with self.assertRaises(AttributeError):
- list(qs)
- def test_invalid_qs_list(self):
-
-
- qs = Article.objects.order_by('invalid_column')
- self.assertRaises(FieldError, list, qs)
- self.assertRaises(FieldError, list, qs)
- class NullJoinPromotionOrTest(TestCase):
- def setUp(self):
- self.d1 = ModelD.objects.create(name='foo')
- d2 = ModelD.objects.create(name='bar')
- self.a1 = ModelA.objects.create(name='a1', d=self.d1)
- c = ModelC.objects.create(name='c')
- b = ModelB.objects.create(name='b', c=c)
- self.a2 = ModelA.objects.create(name='a2', b=b, d=d2)
- def test_ticket_17886(self):
-
-
-
-
-
- q_obj = (
- Q(d__name='foo')|
- Q(b__name='foo')|
- Q(b__c__name='foo')
- )
- qset = ModelA.objects.filter(q_obj)
- self.assertEqual(list(qset), [self.a1])
-
-
-
- self.assertEqual(str(qset.query).count('INNER JOIN'), 1)
- def test_isnull_filter_promotion(self):
- qs = ModelA.objects.filter(Q(b__name__isnull=True))
- self.assertEqual(str(qs.query).count('LEFT OUTER'), 1)
- self.assertEqual(list(qs), [self.a1])
- qs = ModelA.objects.filter(~Q(b__name__isnull=True))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- self.assertEqual(list(qs), [self.a2])
- qs = ModelA.objects.filter(~~Q(b__name__isnull=True))
- self.assertEqual(str(qs.query).count('LEFT OUTER'), 1)
- self.assertEqual(list(qs), [self.a1])
- qs = ModelA.objects.filter(Q(b__name__isnull=False))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- self.assertEqual(list(qs), [self.a2])
- qs = ModelA.objects.filter(~Q(b__name__isnull=False))
- self.assertEqual(str(qs.query).count('LEFT OUTER'), 1)
- self.assertEqual(list(qs), [self.a1])
- qs = ModelA.objects.filter(~~Q(b__name__isnull=False))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- self.assertEqual(list(qs), [self.a2])
- class ReverseJoinTrimmingTest(TestCase):
- def test_reverse_trimming(self):
-
-
-
- t = Tag.objects.create()
- qs = Tag.objects.filter(annotation__tag=t.pk)
- self.assertIn('INNER JOIN', str(qs.query))
- self.assertEqual(list(qs), [])
- class JoinReuseTest(TestCase):
- """
- Test that the queries reuse joins sensibly (for example, direct joins
- are always reused).
- """
- def test_fk_reuse(self):
- qs = Annotation.objects.filter(tag__name='foo').filter(tag__name='bar')
- self.assertEqual(str(qs.query).count('JOIN'), 1)
- def test_fk_reuse_select_related(self):
- qs = Annotation.objects.filter(tag__name='foo').select_related('tag')
- self.assertEqual(str(qs.query).count('JOIN'), 1)
- def test_fk_reuse_annotation(self):
- qs = Annotation.objects.filter(tag__name='foo').annotate(cnt=Count('tag__name'))
- self.assertEqual(str(qs.query).count('JOIN'), 1)
- def test_fk_reuse_disjunction(self):
- qs = Annotation.objects.filter(Q(tag__name='foo') | Q(tag__name='bar'))
- self.assertEqual(str(qs.query).count('JOIN'), 1)
- def test_fk_reuse_order_by(self):
- qs = Annotation.objects.filter(tag__name='foo').order_by('tag__name')
- self.assertEqual(str(qs.query).count('JOIN'), 1)
- def test_revo2o_reuse(self):
- qs = Detail.objects.filter(member__name='foo').filter(member__name='foo')
- self.assertEqual(str(qs.query).count('JOIN'), 1)
- def test_revfk_noreuse(self):
- qs = Author.objects.filter(report__name='r4').filter(report__name='r1')
- self.assertEqual(str(qs.query).count('JOIN'), 2)
- class DisjunctionPromotionTests(TestCase):
- def test_disjuction_promotion_select_related(self):
- fk1 = FK1.objects.create(f1='f1', f2='f2')
- basea = BaseA.objects.create(a=fk1)
- qs = BaseA.objects.filter(Q(a=fk1) | Q(b=2))
- self.assertEqual(str(qs.query).count(' JOIN '), 0)
- qs = qs.select_related('a', 'b')
- self.assertEqual(str(qs.query).count(' INNER JOIN '), 0)
- self.assertEqual(str(qs.query).count(' LEFT OUTER JOIN '), 2)
- with self.assertNumQueries(1):
- self.assertQuerysetEqual(qs, [basea], lambda x: x)
- self.assertEqual(qs[0].a, fk1)
- self.assertIs(qs[0].b, None)
- def test_disjunction_promotion1(self):
-
-
- qs = BaseA.objects.filter(a__f1='foo')
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- qs = qs.filter(Q(b__f1='foo') | Q(b__f2='foo'))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 2)
-
- qs = BaseA.objects.filter(Q(b__f1='foo') | Q(b__f2='foo'))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- qs = qs.filter(a__f1='foo')
- self.assertEqual(str(qs.query).count('INNER JOIN'), 2)
- def test_disjunction_promotion2(self):
- qs = BaseA.objects.filter(a__f1='foo')
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
-
-
- qs = qs.filter(Q(b__f1='foo') | Q(c__f2='foo'))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 2)
-
- qs = BaseA.objects.filter(Q(b__f1='foo') | Q(c__f2='foo'))
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 2)
- qs = qs.filter(a__f1='foo')
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 2)
- def test_disjunction_promotion3(self):
- qs = BaseA.objects.filter(a__f2='bar')
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
-
-
-
- qs = qs.filter(Q(a__f1='foo') | Q(b__f2='foo'))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 1)
- @unittest.expectedFailure
- def test_disjunction_promotion3_failing(self):
-
-
-
-
- qs = BaseA.objects.filter(
- Q(a__f1='foo') | Q(b__f2='foo')).filter(a__f2='bar')
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 1)
- @unittest.expectedFailure
- def test_disjunction_promotion4_failing(self):
-
- qs = BaseA.objects.filter(Q(a=1) | Q(a=2))
- self.assertEqual(str(qs.query).count('JOIN'), 0)
- qs = qs.filter(a__f1='foo')
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- def test_disjunction_promotion4(self):
- qs = BaseA.objects.filter(a__f1='foo')
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- qs = qs.filter(Q(a=1) | Q(a=2))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- @unittest.expectedFailure
- def test_disjunction_promotion5_failing(self):
-
- qs = BaseA.objects.filter(Q(a=1) | Q(a=2))
-
-
- self.assertEqual(str(qs.query).count('JOIN'), 0)
- qs = qs.filter(Q(a__f1='foo') | Q(b__f1='foo'))
-
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 1)
- qs = BaseA.objects.filter(Q(a__f1='foo') | Q(b__f1='foo'))
-
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 0)
- qs = qs.objects.filter(Q(a=1) | Q(a=2))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 1)
- def test_disjunction_promotion6(self):
- qs = BaseA.objects.filter(Q(a=1) | Q(a=2))
- self.assertEqual(str(qs.query).count('JOIN'), 0)
- qs = BaseA.objects.filter(Q(a__f1='foo') & Q(b__f1='foo'))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 2)
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 0)
- qs = BaseA.objects.filter(Q(a__f1='foo') & Q(b__f1='foo'))
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 0)
- self.assertEqual(str(qs.query).count('INNER JOIN'), 2)
- qs = qs.filter(Q(a=1) | Q(a=2))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 2)
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 0)
- def test_disjunction_promotion7(self):
- qs = BaseA.objects.filter(Q(a=1) | Q(a=2))
- self.assertEqual(str(qs.query).count('JOIN'), 0)
- qs = BaseA.objects.filter(Q(a__f1='foo') | (Q(b__f1='foo') & Q(a__f1='bar')))
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 1)
- qs = BaseA.objects.filter(
- (Q(a__f1='foo') | Q(b__f1='foo')) & (Q(a__f1='bar') | Q(c__f1='foo'))
- )
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 3)
- self.assertEqual(str(qs.query).count('INNER JOIN'), 0)
- qs = BaseA.objects.filter(
- (Q(a__f1='foo') | (Q(a__f1='bar')) & (Q(b__f1='bar') | Q(c__f1='foo')))
- )
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 2)
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- def test_disjunction_promotion_fexpression(self):
- qs = BaseA.objects.filter(Q(a__f1=F('b__f1')) | Q(b__f1='foo'))
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 1)
- self.assertEqual(str(qs.query).count('INNER JOIN'), 1)
- qs = BaseA.objects.filter(Q(a__f1=F('c__f1')) | Q(b__f1='foo'))
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 3)
- qs = BaseA.objects.filter(Q(a__f1=F('b__f1')) | Q(a__f2=F('b__f2')) | Q(c__f1='foo'))
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 3)
- qs = BaseA.objects.filter(Q(a__f1=F('c__f1')) | (Q(pk=1) & Q(pk=2)))
- self.assertEqual(str(qs.query).count('LEFT OUTER JOIN'), 2)
- self.assertEqual(str(qs.query).count('INNER JOIN'), 0)
- class ManyToManyExcludeTest(TestCase):
- def test_exclude_many_to_many(self):
- Identifier.objects.create(name='extra')
- program = Program.objects.create(identifier=Identifier.objects.create(name='program'))
- channel = Channel.objects.create(identifier=Identifier.objects.create(name='channel'))
- channel.programs.add(program)
-
-
- self.assertQuerysetEqual(
- Identifier.objects.exclude(program__channel=channel).order_by('name'),
- ['<Identifier: channel>', '<Identifier: extra>']
- )
- self.assertQuerysetEqual(
- Identifier.objects.exclude(program__channel=None).order_by('name'),
- ['<Identifier: program>']
- )
- def test_ticket_12823(self):
- pg3 = Page.objects.create(text='pg3')
- pg2 = Page.objects.create(text='pg2')
- pg1 = Page.objects.create(text='pg1')
- pa1 = Paragraph.objects.create(text='pa1')
- pa1.page = [pg1, pg2]
- pa2 = Paragraph.objects.create(text='pa2')
- pa2.page = [pg2, pg3]
- pa3 = Paragraph.objects.create(text='pa3')
- ch1 = Chapter.objects.create(title='ch1', paragraph=pa1)
- ch2 = Chapter.objects.create(title='ch2', paragraph=pa2)
- ch3 = Chapter.objects.create(title='ch3', paragraph=pa3)
- b1 = Book.objects.create(title='b1', chapter=ch1)
- b2 = Book.objects.create(title='b2', chapter=ch2)
- b3 = Book.objects.create(title='b3', chapter=ch3)
- q = Book.objects.exclude(chapter__paragraph__page__text='pg1')
- self.assertNotIn('IS NOT NULL', str(q.query))
- self.assertEqual(len(q), 2)
- self.assertNotIn(b1, q)
- self.assertIn(b2, q)
- self.assertIn(b3, q)
- class RelabelCloneTest(TestCase):
- def test_ticket_19964(self):
- my1 = MyObject.objects.create(data='foo')
- my1.parent = my1
- my1.save()
- my2 = MyObject.objects.create(data='bar', parent=my1)
- parents = MyObject.objects.filter(parent=F('id'))
- children = MyObject.objects.filter(parent__in=parents).exclude(parent=F('id'))
- self.assertEqual(list(parents), [my1])
-
-
- self.assertEqual(list(children), [my2])
- self.assertEqual(list(parents), [my1])
- class Ticket20101Tests(TestCase):
- def test_ticket_20101(self):
- """
- Tests QuerySet ORed combining in exclude subquery case.
- """
- t = Tag.objects.create(name='foo')
- a1 = Annotation.objects.create(tag=t, name='a1')
- a2 = Annotation.objects.create(tag=t, name='a2')
- a3 = Annotation.objects.create(tag=t, name='a3')
- n = Note.objects.create(note='foo', misc='bar')
- qs1 = Note.objects.exclude(annotation__in=[a1, a2])
- qs2 = Note.objects.filter(annotation__in=[a3])
- self.assertTrue(n in qs1)
- self.assertFalse(n in qs2)
- self.assertTrue(n in (qs1 | qs2))
- class EmptyStringPromotionTests(TestCase):
- def test_empty_string_promotion(self):
- qs = RelatedObject.objects.filter(single__name='')
- if connection.features.interprets_empty_strings_as_nulls:
- self.assertIn('LEFT OUTER JOIN', str(qs.query))
- else:
- self.assertNotIn('LEFT OUTER JOIN', str(qs.query))
- class ValuesSubqueryTests(TestCase):
- def test_values_in_subquery(self):
-
-
- o1 = Order.objects.create(id=-2)
- o2 = Order.objects.create(id=-1)
- oi1 = OrderItem.objects.create(order=o1, status=0)
- oi1.status = oi1.pk
- oi1.save()
- OrderItem.objects.create(order=o2, status=0)
-
-
- self.assertQuerysetEqual(
- Order.objects.filter(items__in=OrderItem.objects.values_list('status')),
- [o1.pk], lambda x: x.pk)
- class DoubleInSubqueryTests(TestCase):
- def test_double_subquery_in(self):
- lfa1 = LeafA.objects.create(data='foo')
- lfa2 = LeafA.objects.create(data='bar')
- lfb1 = LeafB.objects.create(data='lfb1')
- lfb2 = LeafB.objects.create(data='lfb2')
- Join.objects.create(a=lfa1, b=lfb1)
- Join.objects.create(a=lfa2, b=lfb2)
- leaf_as = LeafA.objects.filter(data='foo').values_list('pk', flat=True)
- joins = Join.objects.filter(a__in=leaf_as).values_list('b__id', flat=True)
- qs = LeafB.objects.filter(pk__in=joins)
- self.assertQuerysetEqual(
- qs, [lfb1], lambda x: x)
- class Ticket18785Tests(unittest.TestCase):
- def test_ticket_18785(self):
-
- qs = Item.objects.exclude(
- note__isnull=False
- ).filter(
- name='something', creator__extra__isnull=True
- ).order_by()
- self.assertEqual(1, str(qs.query).count('INNER JOIN'))
- self.assertEqual(0, str(qs.query).count('OUTER JOIN'))
|