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

您的位置:首頁技術文章
文章詳情頁

Django QuerySet查詢集原理及代碼實例

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

一 概念

Django的ORM中存在查詢集的概念。

查詢集,也稱查詢結果集、QuerySet,表示從數據庫中獲取的對象集合。

當調用如下過濾器方法時,Django會返回查詢集(而不是簡單的列表):

all():返回所有數據。 filter():返回滿足條件的數據。 exclude():返回滿足條件之外的數據。 order_by():對結果進行排序。

對查詢集可以再次調用過濾器進行過濾,也就意味著查詢集可以含有零個、一個或多個過濾器。過濾器基于所給的參數限制查詢的結果。

從SQL的角度講,查詢集與select語句等價,過濾器像where、limit、order by子句。

二 兩大特性

1)惰性執行

創建查詢集不會訪問數據庫,直到調用數據時,才會訪問數據庫,調用數據的情況包括迭代、序列化、與if合用

例如,當執行如下語句時,并未進行數據庫查詢,只是創建了一個查詢集qs

# 查詢BookInfo模型類中的所有數據qs = BookInfo.objects.all() # 繼續執行遍歷迭代操作后,才真正的進行了數據庫的查詢for book in qs: print(book.btitle)

2)緩存

使用同一個查詢集,第一次使用時會發生數據庫的查詢,然后Django會把結果緩存下來,再次使用這個查詢集時會使用緩存的數據,減少了數據庫的查詢次數。

情況一:如下是兩個查詢集,無法重用緩存,每次查詢都會與數據庫進行一次交互,增加了數據庫的負載。

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

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

情況二:經過存儲后,可以重用查詢集,第二次使用緩存中的數據。

# 首先獲得一個查詢集qs=BookInfo.objects.all()# 第一次讀取數據,會查詢數據庫,然后增加緩存[book.id for book in qs]# 第二次讀取數據,直接查詢緩存[book.id for book in qs]

3)何時查詢集不會被緩存?

查詢集不會永遠緩存它們的結果。當只對查詢集的部分進行求值時會檢查緩存, 如果這個部分不在緩存中,那么接下來查詢返回的記錄都將不會被緩存。所以,這意味著使用切片或索引來限制查詢集將不會填充緩存。

情況一:重復獲取查詢集對象中一個特定的索引將每次都查詢數據庫:

queryset = BookInfo.objects.all()

queryset[5] # 查詢數據庫queryset[5] # 再一次查詢數據庫

情況二:如果已經對全部查詢集求值過,則將檢查緩存:

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

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

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

注:簡單地打印查詢集不會填充緩存。

queryResult=models.Article.objects.all()print(queryResult) # 查詢數據庫print(queryResult) # 查詢數據庫 

三 限制查詢集

1)、可以對查詢集進行取下標或切片操作,等同于sql中的limit和offset子句。

注意:不支持負數索引。對查詢集進行切片后返回一個新的查詢集,不會立即執行查詢。

如果獲取一個對象,直接使用[0],等同于[0:1].get(),但是如果沒有數據,[0]引發IndexError異常,[0:1].get()如果沒有數據引發DoesNotExist異常。

示例:獲取第1、2項,運行查看。

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

2)、exists()方法:判斷某一個查詢集中是否有數據:

簡單的使用if語句進行判斷也會完全執行整個queryset并且把數據放入cache,雖然你并不需要這些 數據!為了避免這個,可以用exists()方法,判斷查詢集中是否有數據,如果有則返回True,沒有則返回False。

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

3)、terator()方法: 來獲取數據,處理完數據就將其丟棄。

當queryset非常巨大時,cache會成為問題。

處理成千上萬的記錄時,將它們一次裝入內存是很浪費的。更糟糕的是,巨大的queryset可能會鎖住系統 進程,讓你的程序瀕臨崩潰。要避免在遍歷數據的同時產生queryset cache,可以使用iterator()方法 來獲取數據,處理完數據就將其丟棄。

objs = BookInfo.objects.all().iterator()# iterator()可以一次只從數據庫獲取少量數據,這樣可以節省內存for obj in objs: print(obj.title)#BUT,再次遍歷沒有打印,因為迭代器已經在上一次遍歷(next)到最后一次了,沒得遍歷了for obj in objs: print(obj.title)

注:(1) 使用iterator()方法來防止生成cache,意味著遍歷同一個queryset時會重復執行查詢。所以使 #用iterator()的時候要當心,確保你的代碼在操作一個大的queryset時沒有重復執行查詢。

(2) queryset的cache是用于減少程序對數據庫的查詢,在通常的使用下會保證只有在需要的時候才會查詢數據庫。 使用exists()和iterator()方法可以優化程序對內存的使用。不過,由于它們并不會生成queryset cache,可能 會造成額外的數據庫查詢。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持好吧啦網。

標簽: Django
相關文章:
主站蜘蛛池模板: 国产一区免费在线观看 | 国产精品拍自在线观看 | 韩国欧洲一级毛片免费 | 日韩欧美精品在线视频 | 欧美成人高清在线视频大全 | 91精品人成在线观看 | 九九精品免费观看在线 | 看三级毛片 | 久久99精品综合国产首页 | 好吊操这里只有精品 | www.碰 | 日本特黄特色大片免费视频网站 | 伊人黄色片 | 91香蕉网 | 午夜亚洲精品 | 国产精品无码久久av | 全免费a级毛片免费看不卡 全免费毛片在线播放 | 亚洲成年 | 伊人久久在线 | 仑乱高清在线一级播放 | 毛片网站视频 | 美女精品永久福利在线 | 欧美一级aa天码毛片 | 狠狠色婷婷丁香综合久久韩国 | www.操操操 | jizzjizz成熟丰满舒服 | 草草影院www色极品欧美 | 精品国产看高清国产毛片 | 欧美性精品videofree | 亚洲高清成人欧美动作片 | 国产精品亚洲欧美一级久久精品 | 美国毛片亚洲社区在线观看 | 国产性生活 | 亚洲一区亚洲二区 | 国产精品爱久久久久久久小 | 午夜欧美在线 | 美日韩黄色片 | 久久精品中文字幕免费 | 成人黄色三级 | 国产一区二区三区国产精品 | 欧美成人高清在线视频大全 |