天天看點

轉一篇:文檔筆記之Django QuerySet

這個放着,說不定以後作一些更深入的查詢時,用得着的。

http://www.rapospectre.com/blog/7/

今天剛剛答完辯體完檢就跑來更新部落格了!!!

先補上第一篇:

一般情況下,我們在寫django項目需要操作queryset時一些常用的方法已經滿足我們日常大多數需求,比如get、filter、exclude、delete神馬的感覺就已經無所不能了,但随着項目但業務邏輯越來越複雜,這幾個方法可能就不能很好但滿足我們了,是以這時候,最好的辦法是神馬??對,讀文檔!這裡的讀文檔不是有業務需求時去查文檔,而是要為了閱讀文檔而閱讀文檔。以下也是作為我的檔案閱讀筆記,我記下了一些我以後可能會用到或者一些技巧性提升的東西,好,不廢話,正文開始:

首先,我們假設有以下兩個model:

1、annotate(args, *kwargs)

為queryset增加注解,神馬是注解?就是你讀出queryset可能會需要一些額外資料要添加進去的時候,你就可以用這個東東咯,使用方法看代碼:

blog model 類本身并沒有定義 entry__count 屬性,但可以使用注解函式的關系字參數,進而改變注解的命名:

2、aggregate(args, *kwargs) 這個參數有點像annotate的反義,annotate傳回的是一個包含注解值的queryset,而aggregate則單獨傳回注解值,傳回類型是一個dict,當然,這種方式在文檔中叫做聚合查詢,具體使用如下:

通過在 aggregate 指定關鍵字參數,你可以控制傳回的聚合名稱:

3、defer(*fields) 延後讀取字段。啥意思?我讀文檔時就這感覺。。後來發現是醬紫滴,一個複雜滴model可能你從資料庫中讀出後根本不需要某些字段,讀了又浪費時間浪費空間,怎麼辦?對!用defer,延後讀取,你可以在defer中指定一個或多個字段,也可用鍊式方法使用defer,它傳回對依然是個完整對queryset但其中defer指定但字段并沒有真但從資料庫讀出來,隻有當你通路這些延後字段時django才會從資料庫讀取這些資料,感覺在資料量變大後用這個方法很nice,具體用法如下:

不過要注意的是,不能用defer過的字段進行order_by操作,這樣做木有作用滴,如果需要清楚defer,隻要加個<code>defer(none)</code>就ok啦。

你還闊以defer model中的外鍵,但是你需要提使用 select_related() 載入關聯 model,具體用法:

4、only(*fields) 我想你已經猜到了,一定是defer相反的咯,是啊是啊,沒錯。only會立即查詢指定的字段,但是要注意了,這有坑,only隻傳回指定的字段,其他木有指定的預設就給defer了喲,是以以下寫法是等價滴:

當你使用鍊式方法調用only時隻有最後一個only内的參數會立即傳回,其他參數都會被defer,注意這裡only的覆寫性~

5、create(**kwargs) 建立并儲存對象。一般我們要建立一個model對象時直接使用他的構造函數或者使用<code>.</code>文法指派,最後調用<code>.save()</code>方法儲存。那麼在我們已經知道建立這個對象所有必須資料的情況下,其實用create會更快捷,代碼看着更幹淨,起使用方法與構造方法類似,隻是不需要調用<code>.save()</code>啦, 例子如下:

6、get_or_create(kwargs) 和 update_or_create(kwargs)

嗯,看看就知道這個是<code>create</code>的更新版,沒錯,他們倆一個是在查無此資料後建立一個是更新不存在資料時建立,具體用法同<code>create</code>,<code>get_or_create</code>等效如下過程:

注意這兩個方法的傳回值,他們傳回兩個東東:

其中<code>created</code>是個bool值,當此方法生成了一個新的model object,此值為true,反之為false,<code>obj</code>則是生成的object或者查到的object執行個體。

7、latest(field_name=none) 和 earliest(field_name=none) 分别傳回指定字段的最新資料與最早資料。

8、first() 和 last() 分别傳回queryset的第一項與最後一項,具體用法如下:

等同于:

9、update(**kwargs) 用于更新一組資料,但要注意,它不能更新外鍵, 不能更新切片過的queryset以及不能再被切片的set,用法如下:

10、delete() 有人肯定要說了,部落客你再逗我,這個方法擡頭不見低頭見,還用你說?!是啊是啊,删除普通資料的時候當然木有什麼,但是如果删除外健關系很複雜的object時有木有想過細節?是不是細思極恐 啊#_# 比如,以我們開頭的model為例,我删了一個entry執行個體,那麼與它有外健關聯的blog執行個體會怎樣?一同被删了?還是保留?保留的話那他對應的entry外健是神馬?wtf! 嗯,實話告訴你,預設情況下調用<code>delete()</code>是會删除所有有關的外鍵對象的(是不是突然感覺自己之前代碼裡有坑了)是以我們需要詳細說說這個方法,如何做才能讓他不删除對應的外鍵或者說按照我們想象的方式進行删除呢?

答案在這裡:

django.models 的<code>on_delete</code>參數,此參數有以下幾個可選值:

cascade:這就是delete()的預設選項,也就是關聯删除

protect:如果删除的model obj含有外鍵則引起 protectederror

set_null:就是把外鍵置空咯,當然前提是你得設定外鍵的<code>null=true</code>

set_default:就是把外鍵設為預設咯,當然前提是你得設定外鍵的<code>default=xxx</code>

set():set内應是一個函數,用來傳回一個外鍵執行個體,用法如下:

11、fields lookups 強大滴django fields lookups,具體可選參數有:

iexact icontains in istartwith gt gte lt lte endwith iendwith range year month day week_day hour minute second insole (ex: search) iregex

其中,首字母帶“i”的意思就是不分大小寫,如果需要大小寫敏感就把“i”去掉啦~其他參數大體從字面意思就知道啦,改天補上詳細的�例子。

12、avg、count、sum、max、min、stddev、variance 這些方法就是求資料的相應結果咯,比如avg就是平均值啦,嗯,基本都看得懂,除了後兩個,一個是方差,一個是标準差,具體用法其實前文裡有,我還是放一下:

13、強大的q查詢與f查詢: 嗯,這一部分先留着,總之告訴你很膩害就是了,可以做很複雜的查詢,先放個例子:

這是一個或查詢,滿足其中一個條件的資料會被傳回。

好,我們下期再見(對,部落客懶病犯了,反正也沒人看2333333)