色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Django QuerySet查詢(xún)集原理及代碼實(shí)例

瀏覽:142日期:2024-09-29 11:05:17

一 概念

Django的ORM中存在查詢(xún)集的概念。

查詢(xún)集,也稱(chēng)查詢(xún)結(jié)果集、QuerySet,表示從數(shù)據(jù)庫(kù)中獲取的對(duì)象集合。

當(dāng)調(diào)用如下過(guò)濾器方法時(shí),Django會(huì)返回查詢(xún)集(而不是簡(jiǎn)單的列表):

all():返回所有數(shù)據(jù)。 filter():返回滿(mǎn)足條件的數(shù)據(jù)。 exclude():返回滿(mǎn)足條件之外的數(shù)據(jù)。 order_by():對(duì)結(jié)果進(jìn)行排序。

對(duì)查詢(xún)集可以再次調(diào)用過(guò)濾器進(jìn)行過(guò)濾,也就意味著查詢(xún)集可以含有零個(gè)、一個(gè)或多個(gè)過(guò)濾器。過(guò)濾器基于所給的參數(shù)限制查詢(xún)的結(jié)果。

從SQL的角度講,查詢(xún)集與select語(yǔ)句等價(jià),過(guò)濾器像where、limit、order by子句。

二 兩大特性

1)惰性執(zhí)行

創(chuàng)建查詢(xún)集不會(huì)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),直到調(diào)用數(shù)據(jù)時(shí),才會(huì)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),調(diào)用數(shù)據(jù)的情況包括迭代、序列化、與if合用

例如,當(dāng)執(zhí)行如下語(yǔ)句時(shí),并未進(jìn)行數(shù)據(jù)庫(kù)查詢(xún),只是創(chuàng)建了一個(gè)查詢(xún)集qs

# 查詢(xún)BookInfo模型類(lèi)中的所有數(shù)據(jù)qs = BookInfo.objects.all() # 繼續(xù)執(zhí)行遍歷迭代操作后,才真正的進(jìn)行了數(shù)據(jù)庫(kù)的查詢(xún)for book in qs: print(book.btitle)

2)緩存

使用同一個(gè)查詢(xún)集,第一次使用時(shí)會(huì)發(fā)生數(shù)據(jù)庫(kù)的查詢(xún),然后Django會(huì)把結(jié)果緩存下來(lái),再次使用這個(gè)查詢(xún)集時(shí)會(huì)使用緩存的數(shù)據(jù),減少了數(shù)據(jù)庫(kù)的查詢(xún)次數(shù)。

情況一:如下是兩個(gè)查詢(xún)集,無(wú)法重用緩存,每次查詢(xún)都會(huì)與數(shù)據(jù)庫(kù)進(jìn)行一次交互,增加了數(shù)據(jù)庫(kù)的負(fù)載。

from booktest.models import BookInfo# 每個(gè)列表內(nèi)都為一個(gè)獨(dú)立的查詢(xún)集,兩次查詢(xún)集之間如果有數(shù)據(jù)插入,可能數(shù)據(jù)集會(huì)不同[book.id for book in BookInfo.objects.all()]

[book.id for book in BookInfo.objects.all()]

情況二:經(jīng)過(guò)存儲(chǔ)后,可以重用查詢(xún)集,第二次使用緩存中的數(shù)據(jù)。

# 首先獲得一個(gè)查詢(xún)集qs=BookInfo.objects.all()# 第一次讀取數(shù)據(jù),會(huì)查詢(xún)數(shù)據(jù)庫(kù),然后增加緩存[book.id for book in qs]# 第二次讀取數(shù)據(jù),直接查詢(xún)緩存[book.id for book in qs]

3)何時(shí)查詢(xún)集不會(huì)被緩存?

查詢(xún)集不會(huì)永遠(yuǎn)緩存它們的結(jié)果。當(dāng)只對(duì)查詢(xún)集的部分進(jìn)行求值時(shí)會(huì)檢查緩存, 如果這個(gè)部分不在緩存中,那么接下來(lái)查詢(xún)返回的記錄都將不會(huì)被緩存。所以,這意味著使用切片或索引來(lái)限制查詢(xún)集將不會(huì)填充緩存。

情況一:重復(fù)獲取查詢(xún)集對(duì)象中一個(gè)特定的索引將每次都查詢(xún)數(shù)據(jù)庫(kù):

queryset = BookInfo.objects.all()

queryset[5] # 查詢(xún)數(shù)據(jù)庫(kù)queryset[5] # 再一次查詢(xún)數(shù)據(jù)庫(kù)

情況二:如果已經(jīng)對(duì)全部查詢(xún)集求值過(guò),則將檢查緩存:

# 獲取查詢(xún)集queryset = BookInfo.objects.all()[entry for entry in queryset] # 查詢(xún)數(shù)據(jù)庫(kù)print queryset[5] # 使用緩存 print queryset[5] # 使用緩存

情況三:下面是一些其它例子,它們會(huì)使得全部的查詢(xún)集被求值并填充到緩存中:

# 獲取查詢(xún)集queryset = BookInfo.objects.all()[entry for entry in queryset]bool(queryset)entry in querysetlist(queryset)

注:簡(jiǎn)單地打印查詢(xún)集不會(huì)填充緩存。

queryResult=models.Article.objects.all()print(queryResult) # 查詢(xún)數(shù)據(jù)庫(kù)print(queryResult) # 查詢(xún)數(shù)據(jù)庫(kù) 

三 限制查詢(xún)集

1)、可以對(duì)查詢(xún)集進(jìn)行取下標(biāo)或切片操作,等同于sql中的limit和offset子句。

注意:不支持負(fù)數(shù)索引。對(duì)查詢(xún)集進(jìn)行切片后返回一個(gè)新的查詢(xún)集,不會(huì)立即執(zhí)行查詢(xún)。

如果獲取一個(gè)對(duì)象,直接使用[0],等同于[0:1].get(),但是如果沒(méi)有數(shù)據(jù),[0]引發(fā)IndexError異常,[0:1].get()如果沒(méi)有數(shù)據(jù)引發(fā)DoesNotExist異常。

示例:獲取第1、2項(xiàng),運(yùn)行查看。

qs = BookInfo.objects.all()[0:2]

2)、exists()方法:判斷某一個(gè)查詢(xún)集中是否有數(shù)據(jù):

簡(jiǎn)單的使用if語(yǔ)句進(jìn)行判斷也會(huì)完全執(zhí)行整個(gè)queryset并且把數(shù)據(jù)放入cache,雖然你并不需要這些 數(shù)據(jù)!為了避免這個(gè),可以用exists()方法,判斷查詢(xún)集中是否有數(shù)據(jù),如果有則返回True,沒(méi)有則返回False。

if queryResult.exists():#SELECT (1) AS 'a' FROM 'blog_article' LIMIT 1; args=()print('exists...')

3)、terator()方法: 來(lái)獲取數(shù)據(jù),處理完數(shù)據(jù)就將其丟棄。

當(dāng)queryset非常巨大時(shí),cache會(huì)成為問(wèn)題。

處理成千上萬(wàn)的記錄時(shí),將它們一次裝入內(nèi)存是很浪費(fèi)的。更糟糕的是,巨大的queryset可能會(huì)鎖住系統(tǒng) 進(jìn)程,讓你的程序?yàn)l臨崩潰。要避免在遍歷數(shù)據(jù)的同時(shí)產(chǎn)生queryset cache,可以使用iterator()方法 來(lái)獲取數(shù)據(jù),處理完數(shù)據(jù)就將其丟棄。

objs = BookInfo.objects.all().iterator()# iterator()可以一次只從數(shù)據(jù)庫(kù)獲取少量數(shù)據(jù),這樣可以節(jié)省內(nèi)存for obj in objs: print(obj.title)#BUT,再次遍歷沒(méi)有打印,因?yàn)榈饕呀?jīng)在上一次遍歷(next)到最后一次了,沒(méi)得遍歷了for obj in objs: print(obj.title)

注:(1) 使用iterator()方法來(lái)防止生成cache,意味著遍歷同一個(gè)queryset時(shí)會(huì)重復(fù)執(zhí)行查詢(xún)。所以使 #用iterator()的時(shí)候要當(dāng)心,確保你的代碼在操作一個(gè)大的queryset時(shí)沒(méi)有重復(fù)執(zhí)行查詢(xún)。

(2) queryset的cache是用于減少程序?qū)?shù)據(jù)庫(kù)的查詢(xún),在通常的使用下會(huì)保證只有在需要的時(shí)候才會(huì)查詢(xún)數(shù)據(jù)庫(kù)。 使用exists()和iterator()方法可以?xún)?yōu)化程序?qū)?nèi)存的使用。不過(guò),由于它們并不會(huì)生成queryset cache,可能 會(huì)造成額外的數(shù)據(jù)庫(kù)查詢(xún)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Django
相關(guān)文章:
主站蜘蛛池模板: 亚洲黄色三级网站 | 欧美一级在线观看播放 | 日韩美女一级片 | 毛片免费视频观看 | 91久久国产露脸精品 | 高清不卡毛片 | 亚洲深夜视频 | 欧美日本在线三级视频 | 欧美一级毛片高清视频 | 三级毛片在线播放 | 成人精品一区久久久久 | 一本色道久久88 | 久久毛片久久毛 | 成人免费福利片在线观看 | 国内精品视频九九九九 | 成人欧美一区二区三区在线 | 国产菲菲视频在线观看 | 国产高清a毛片在线看 | 欧美日韩视频一区二区三区 | 久草亚洲视频 | 亚洲一区二区三区视频 | 欧美大片一区二区三区 | 网站免费满18成年在线观看 | 亚洲精品欧洲一区二区三区 | 中文字幕高清在线天堂网 | 国产自愉自愉全免费高清 | 欧美1区二区三区公司 | 精品热99| 久草资源免费 | 欧美国产综合在线 | 亚洲一区二区三区成人 | 九九51精品国产免费看 | 最新在线精品国自拍视频 | 天天拍拍夜夜出水 | avtom影院入口永久在线观看 | a级性生活视频 | 视频一区亚洲 | 国产亚洲欧洲一区二区三区 | 可以免费看黄的网站 | 91精品国产一区二区三区左线 | 国产一区二区三区在线观看视频 |