簡介
- 查詢集表示從數(shù)據(jù)庫中獲取的對象集合
- 查詢集可以含有零個由桌、一個或多個過濾器
- 過濾器基于所給的參數(shù)限制查詢的結(jié)果
- 從Sql的角度,查詢集和select語句等價帆谍,過濾器像where和limit子句
- 接下來主要討論如下知識點
- 查詢集
- 字段查詢:比較運算符伪朽,F(xiàn)對象,Q對象
查詢集
- 在管理器上調(diào)用過濾器方法會返回查詢集
- 查詢集經(jīng)過過濾器篩選后返回新的查詢集汛蝙,因此可以寫成鏈式過濾
-
惰性執(zhí)行:創(chuàng)建查詢集不會帶來任何數(shù)據(jù)庫的訪問烈涮,直到調(diào)用數(shù)據(jù)時,才會訪問數(shù)據(jù)庫
- 何時對查詢集求值:迭代窖剑,序列化坚洽,與if合用
- 返回查詢集的方法,稱為過濾器
- all()
- filter()
- exclude()
- order_by()
- values():一個對象構(gòu)成一個字典西土,然后構(gòu)成一個列表返回
- 寫法:
filter(鍵1=值1,鍵2=值2)
等價于
filter(鍵1=值1).filter(鍵2=值2)
- 返回單個值的方法
- get():返回單個滿足條件的對象
- 如果未找到會引發(fā)"模型類.DoesNotExist"異常
- 如果多條被返回讶舰,會引發(fā)"模型類.MultipleObjectsReturned"異常
- count():返回當前查詢的總條數(shù)
- first():返回第一個對象
- last():返回最后一個對象
- exists():判斷查詢集中是否有數(shù)據(jù),如果有則返回True
限制查詢集
- 查詢集返回列表需了,可以使用下標的方式進行限制跳昼,等同于sql中的limit和offset子句
- 注意:不支持負數(shù)索引
- 使用下標后返回一個新的查詢集,不會立即執(zhí)行查詢
- 如果獲取一個對象肋乍,直接使用[0]鹅颊,等同于[0:1].get(),但是如果沒有數(shù)據(jù)住拭,[0]引發(fā)IndexError異常挪略,[0:1].get()引發(fā)DoesNotExist異常
查詢集的緩存
- 每個查詢集都包含一個緩存來最小化對數(shù)據(jù)庫的訪問
- 在新建的查詢集中历帚,緩存為空滔岳,首次對查詢集求值時,會發(fā)生數(shù)據(jù)庫查詢挽牢,django會將查詢的結(jié)果存在查詢集的緩存中谱煤,并返回請求的結(jié)果,接下來對查詢集求值將重用緩存的結(jié)果
- 情況一:這構(gòu)成了兩個查詢集禽拔,無法重用緩存刘离,每次查詢都會與數(shù)據(jù)庫進行一次交互,增加了數(shù)據(jù)庫的負載
print([e.title for e in Entry.objects.all()])
print([e.title for e in Entry.objects.all()])
- 情況二:兩次循環(huán)使用同一個查詢集睹栖,第二次使用緩存中的數(shù)據(jù)
querylist=Entry.objects.all()
print([e.title for e in querylist])
print([e.title for e in querylist])
- 何時查詢集不會被緩存:當只對查詢集的部分進行求值時會檢查緩存硫惕,但是如果這部分不在緩存中,那么接下來查詢返回的記錄將不會被緩存野来,這意味著使用索引來限制查詢集將不會填充緩存恼除,如果這部分數(shù)據(jù)已經(jīng)被緩存,則直接使用緩存中的數(shù)據(jù)
字段查詢
- 實現(xiàn)where子名,作為方法filter()豁辉、exclude()令野、get()的參數(shù)
- 語法:屬性名稱__比較運算符=值
- 表示兩個下劃線,左側(cè)是屬性名稱徽级,右側(cè)是比較類型
- 對于外鍵气破,使用“屬性名_id”表示外鍵的原始值
- 轉(zhuǎn)義:like語句中使用了%與,匹配數(shù)據(jù)中的%與餐抢,在過濾器中直接寫现使,例如:filter(title__contains="%")=>where title like '%%%',表示查找標題中包含%的
比較運算符
- exact:表示判等弹澎,大小寫敏感朴下;如果沒有寫“ 比較運算符”,表示判等
filter(isDelete=False)
exclude(btitle__contains='傳')
- startswith殴胧、endswith:以value開頭或結(jié)尾,大小寫敏感
exclude(btitle__endswith='傳')
- isnull佩迟、isnotnull:是否為null
filter(btitle__isnull=False)
- 在前面加個i表示不區(qū)分大小寫团滥,如iexact、icontains报强、istarswith灸姊、iendswith
- in:是否包含在范圍內(nèi)
filter(pk__in=[1, 2, 3, 4, 5])
- gt、gte秉溉、lt力惯、lte:大于、大于等于召嘶、小于父晶、小于等于
filter(id__gt=3)
- year、month弄跌、day甲喝、week_day、hour铛只、minute埠胖、second:對日期間類型的屬性進行運算
filter(bpub_date__year=1980)
filter(bpub_date__gt=date(1980, 12, 31))
- 跨關(guān)聯(lián)關(guān)系的查詢:處理join查詢
- 語法:模型類名 <屬性名> <比較>
- 注:可以沒有__<比較>部分,表示等于淳玩,結(jié)果同inner join
- 可返向使用直撤,即在關(guān)聯(lián)的兩個模型中都可以使用
filter(heroinfo_ _hcontent_ _contains='八')
- 查詢的快捷方式:pk,pk表示primary key蜕着,默認的主鍵是id
filter(pk__lt=6)
聚合函數(shù)
- 使用aggregate()函數(shù)返回聚合函數(shù)的值
- 函數(shù):Avg谋竖,Count,Max,Min圈盔,Sum
from django.db.models import Max
maxDate = list.aggregate(Max('bpub_date'))
count = list.count()
F對象
- 可以使用模型的字段A與字段B進行比較豹芯,如果A寫在了等號的左邊,則B出現(xiàn)在等號的右邊驱敲,需要通過F對象構(gòu)造
list.filter(bread__gte=F('bcommet'))
- django支持對F()對象使用算數(shù)運算
list.filter(bread__gte=F('bcommet') * 2)
- F()對象中還可以寫作“模型類__列名”進行關(guān)聯(lián)查詢
list.filter(isDelete=F('heroinfo__isDelete'))
- 對于date/time字段铁蹈,可與timedelta()進行運算
list.filter(bpub_date__lt=F('bpub_date') + timedelta(days=1))
Q對象
- 過濾器的方法中關(guān)鍵字參數(shù)查詢,會合并為And進行
- 需要進行or查詢众眨,使用Q()對象
- Q對象(django.db.models.Q)用于封裝一組關(guān)鍵字參數(shù)握牧,這些關(guān)鍵字參數(shù)與“比較運算符”中的相同
from django.db.models import Q
list.filter(Q(pk_ _lt=6))
- Q對象可以使用&(and)、|(or)操作符組合起來
- 當操作符應(yīng)用在兩個Q對象時娩梨,會產(chǎn)生一個新的Q對象
list.filter(pk_ _lt=6).filter(bcommet_ _gt=10)
list.filter(Q(pk_ _lt=6) | Q(bcommet_ _gt=10))
list.filter(~Q(pk__lt=6))
- 可以使用&|~結(jié)合括號進行分組沿腰,構(gòu)造做生意復雜的Q對象
- 過濾器函數(shù)可以傳遞一個或多個Q對象作為位置參數(shù),如果有多個Q對象狈定,這些參數(shù)的邏輯為and
- 過濾器函數(shù)可以混合使用Q對象和關(guān)鍵字參數(shù)颂龙,所有參數(shù)都將and在一起,Q對象必須位于關(guān)鍵字參數(shù)的前面