queryset是django的model中的一種非常重要的概念, 在編寫django專案時, 我們會經常用到這一概念. 因為後端的**與資料庫的所有互動都是通過它來完成的.
model.objects.
all(
)# 最常見的queryset
queryset 可以被構造,過濾,切片,做為引數傳遞,這些行為都不會對資料庫進行操作. 在使用queryset獲取資料庫中的資料之前, 實際上沒有傳送任何資料庫活動.
也就是說, 合理地利用queryset可以大大減少資料庫的互動次數, 從而使程式能夠以更高的效率執行
queryset具有以下特性:
可切片可迭代
惰性快取
可以使用python的切片語法來限制queryset記錄的數目, 其作用等價於sql的limit
和offset
子句。
>>
> user.objects.
all()[
:5]# (limit 5)
>>
> user.objects.
all()[
5:10]
# (offset 5 limit 5)
queryset是可迭代型別,
>>
> userslist=user.objects.
all(
)>>
>
for user in userslist:
print
(user.name)
當您第一次對其進行迭代時,它將執行其資料庫查詢. 若之後還有語句訪問相同的內容, 這可以直接載入, 不用再訪問資料庫, 這是其另一特性: 快取
就像前面所說的query在被構造,切片等操作時不會對資料庫操作, 這裡就是queryset惰性, 也叫惰性查詢
也就是說單純的建立queryset
那麼, 什麼操作會使queryset進行資料庫活動呢? 官方文件給出了我們很多例子:
迭代(iteration),for i in queryset
切片(slicing), 帶有步長的切片,queryset[::2]
索引,queryset[0]
序列化/快取化(pickling/caching), 將資料儲存到redis中或者記憶體中的時候
repr(). 直接列印,print(queryset)
len().len(queryset)
list().list(queryset)
bool().queryset if queryset else none
序列化快取, 就是先將查詢物件載入到記憶體中以完成序列化,這樣你之後就可以第一時間使用物件(直接從資料庫中讀取資料需要一定時間,這正是快取所想避免的)。
**序列化(pickling)是快取化(caching)**的先行工作,所以在快取查詢時,首先就會進行序列化工作。
這意味著當你反序列化queryset 時,第一時間就會從記憶體中獲得查詢的結果,而不是從資料庫中查詢。
如何實現快取? 先來來看一段**:
>>
> queryset = model.objects.
all(
)>>
>
print
(queryset[1]
)# 訪問了資料庫
>>
>
print
(queryset[1]
)# 再次訪問了資料庫
在這段**中, 對queryset進行兩次索引取值, 每一次取值查詢, 都會訪問資料庫
但如果一次性將queryset中的全部值查詢出來,若再次取值則將檢查快取
>>
> queryset = entry.objects.
all(
)>>
>
[entry for entry in queryset]
# 訪問了資料庫
>>
>
print
(queryset[1]
)# 訪問快取
>>
>
print
(queryset[1]
)# 訪問快取
這就是最簡單的快取化方式
下面是一些其它例子,和上面的for迴圈相同的一點是, 它們會查詢queryset中全部的值並填充到快取中:
>>
>
[entry for entry in queryset]
>>
>
bool
(queryset)
>>
> entry in queryset
>>
>
list
(queryset)
QuerySet的特性 惰性和快取等
原創 2019 08 19 23 04 06 makesths 閱讀數 46 更多分類專欄 django筆記 queryset是django的model中的一種非常重要的概念,在編寫django專案時,我們會經常用到這一概念.因為後端的 與資料庫的所有互動都是通過它來完成的.model.object...
django中queryset的兩大特性
roles roleinfo.objects.all 建立查詢集的時候,是不會訪問資料庫的,直到真正的呼叫資料的時候,才會訪問資料庫,所以 roles roleinfo.objects.all 沒有真正的進行資料庫查詢的,只是建立了乙個資料庫查詢集 呼叫資料,真正的使用資料 1 迭代 2 序列化 3...
大腦的惰性
舉幾個例子 1 題目 傑克正看著安妮,而安妮正看著喬治。傑克已婚,喬治未婚。請問是否有一位已婚人士正在看著一位未婚人士?a 是 b 不是 c 無法確定 你選擇哪個?2 大學時體育課 上課前,我們在觀眾台上玩,當時我們在閒聊 說 誰敢跳下去,當時我們站在第5級台階上,我覺得我不能跳下去,太高了.但是當...