Django QuerySet 進階

更多內容,歡迎關注微信公衆號:Python知音閣。

什麼是QuerySet

QuerySet是Django提供的強大的數據庫接口(API)。正是因爲通過它,我們可以使用filter, exclude, get等方法進行數據庫查詢,而不需要使用原始的SQL語言與數據庫進行交互。從數據庫中查詢出來的結果一般是一個集合,這個集合叫就做 queryset。

1. values_list獲取元組形式結果

比如我們要獲取作者的name和qq這兩個字段的信息

authors = Author.objects.values_list(‘name’, ‘qq’)

2. values獲取字典形式的結果

比如我們要獲取作者的name和qq這兩個字段的信息

authors = Author.objects.values(‘name’, ‘qq’)

注意:

  1. values_list 和 values 返回的並不是真正的 列表 或 字典,也是 queryset,他們也是 lazy evaluation 的(惰性評估,通俗地說,就是用的時候才真正的去數據庫查)

  2. 如果查詢後沒有使用,在數據庫更新後再使用,你發現得到在是新內容!!!如果想要舊內容保持着,數據庫更新後不要變,可以 list 一下

  3. 如果只是遍歷這些結果,沒有必要 list 它們轉成列表(浪費內存,數據量大的時候要更謹慎!!!)

3. annotate 聚合計數,求和,平均數等

3.1計數

計算一下每個作者的文章數

Article.objects.all().values(‘author_id’).annotate(count=Count(‘author’)).values(‘author_id’, ‘count’)

3.2 平均數

求一個作者的所有文章的得分(score)平均值

Article.objects.values(‘author_id’).annotate(avg_score=Avg(‘score’)).values(‘author_id’, ‘avg_score’)

3.3 求和

求一個作者所有文章的總分

Article.objects.values(‘author__name’).annotate(sum_score=Sum(‘score’)).values(‘author__name’, ‘sum_score’)

4. select_related 優化一對一,多對一查詢(減少訪問數據庫的次數)

一篇文章只有一個作者:

articles = Article.objects.all().select_related(‘author’)[:10]

5. prefetch_related優化一對多,多對多查詢

和 select_related 功能類似,但是實現不同。select_related 是使用 SQL JOIN 一次性取出相關的內容。prefetch_related 用於 一對多,多對多 的情況,這時 select_related 用不了,因爲當前一條有好幾條與之相關的內容。

prefetch_related是通過再執行一條額外的SQL語句,然後用 Python 把兩次SQL查詢的內容關聯(joining)到一起

“文章”與“標籤”是多對多的關係:

articles = Article.objects.all().prefetch_related(‘tags’)[:10]

6. defer排除不需要的字段

在複雜的情況下,表中可能有些字段內容非常多,取出來轉化成 Python 對象會佔用大量的資源。

這時候可以用 defer 來排除這些字段,比如我們在文章列表頁,只需要文章的標題和作者,沒有必要把文章的內容也獲取出來(因爲會轉換成python對象,浪費內存)

Article.objects.all().defer(‘content’) # 注意這裏沒有查 content 字段了

7. only僅選擇需要的字段

和 defer 相反,only 用於取出需要的字段,假如我們只需要查出 作者的名稱

Author.objects.all().only(‘name’)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章