更多內容,歡迎關注微信公衆號: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’)
注意:
-
values_list 和 values 返回的並不是真正的 列表 或 字典,也是 queryset,他們也是 lazy evaluation 的(惰性評估,通俗地說,就是用的時候才真正的去數據庫查)
-
如果查詢後沒有使用,在數據庫更新後再使用,你發現得到在是新內容!!!如果想要舊內容保持着,數據庫更新後不要變,可以 list 一下
-
如果只是遍歷這些結果,沒有必要 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’)