Django筆記九之model查詢filter、exclude、annotate、order_by

来源:https://www.cnblogs.com/hunterxiong/archive/2023/03/27/17262727.html
-Advertisement-
Play Games

什麼是 Spdlog 日誌庫 Spdlog 是一個 C++ 的日誌庫,它具有高效、易用、跨平臺等特點。它可以寫入到控制台、文件等輸出目標,支持多種日誌級別、多線程安全等功能,非常適合在 C++ 項目中使用。 Spdlog 日誌庫的歷史和背景 Spdlog 日誌庫最初由 Gabi Melman 開發, ...


在接下來四五篇筆記中,將介紹 model 查詢方法的各個細節,為我們的查詢操作提供各種便利。

本篇筆記將介紹惰性查找、filter、exclude、annotate等方法,目錄如下:

  1. 惰性查找
  2. filter
  3. exclude
  4. annotate
  5. alias
  6. order_by

1、惰性查找

前面我們在介紹 Django 增刪改查的時候,提到過他的惰性查找的規則。

也就是說普通的 filter 語句執行時,系統並不會去查詢資料庫,只有當我們真正使用裡面的數據的時候,才會去查詢資料庫。

那麼以下介紹幾種,使用的時候會查詢資料庫的情況:

迭代

一個 QuerySet 是可迭代的,而且僅會在第一次迭代的時候查詢資料庫:

for e in Entry.objects.all():
	print(e.headline)

切片

需要註意的是,使用 python 里的切片語法不會訪問資料庫,比如:

Entry.objects.all()[:3]

但是,如果使用 step 語法則會訪問資料庫,比如以下語句:

Entry.objects.all()[:10:2]

len()

當我們使用 len() 函數去獲取一個 QuerySet 的長度時,會訪問資料庫,比如:

len(Entry.objects.all())

但是這種做法是不被推薦的,因為他會把 QuerySet 中的所有數據,都載入出來,然後計算長度。

如果想要獲取總數量,我們會使用另一個函數,.count(),這個我們後面會提到。

list()

這個操作會強制查詢資料庫,然後將一個 QuerySet 轉換成 python 里的 list。

entry_list = list(Entry.objects.all())

在一般情況下,是不推薦的,因為相對於 list 而言,QuerySet 可以執行的函數更多。

bool()

判斷是否存在數據:

if Entry.objects.filter(headline='hunter'):
	print('exists')

但是,在Django 里一般也不推薦,因為有更高效的用法,那就是使用 .exists() 函數,這個在後面會詳細介紹。

2、filter()

filter 這個函數前面都有介紹,可以在其中添加符合篩選條件,也可以通過鏈式的形式來操作。

但是鏈式執行的用法是 and 邏輯,如果想要用 or 邏輯,可以使用 Q() 用法來連用,前面也簡單介紹過。

3、exclude()

這個函數與 filter() 函數功能相反,是排除符合條件的數據。

4、annotate()

annotate 這個單詞的意思是 註釋,在 Django 里的用法是,通過對數據進行處理,比如一個表達式,或者是通過外鍵引入一個新的數據欄位,或者是聚合出來一個結果(比如平均值,綜合等),會在每一條返回的數據裡面新增一個前面表達式的結果作為一個新的欄位返回。

比如我們獲取 Blog 這個 model 的時候,Entry 作為它的外鍵關係,我們可以獲取關聯了某條 Blog 的 Entry 的數量,並且作為新的欄位添加到 Blog 里一起返回,其操作如下:

q = Blog.objects.annotate(number_of_entries=Count('entry’))
q[0].number_of_entries

5、alias()

alias() 的用法和 annotate 一樣,都可以創建新的數據欄位,但與 annotate() 不一樣的是,其結果並不會作為一個欄位返回,而是用於在使用的過程中做篩選,比如一個用法如下:

q = Blog.objects.alias(number_of_entries=Count('entry')).filter(number_of_entries__gt=1)

6、order_by()

對於 QuerySet 每次返回的結果,如果 Meta 里有 ordering 參數,使用見上一篇 Meta 的使用筆記,那麼數據就會按照 ordering 的參數對數據進行排序後返回。

如果 Meta 里沒有設置該參數,那麼數據則會在有主鍵 id 的情況下按照 id 的順序返回。

當然,我們也可以使用 order_by() 這個函數來對每一次搜索的數據進行排序的重寫。

正序排序

比如我們想要對 Entry 這個 model 對於 pub_date 進行正序排序:

Entry.objects.filter(pub_date__year=2005).order_by('pub_date')

倒序排序

則可以在欄位名前面加個 - 負號來操作:

Entry.objects.filter(pub_date__year=2005).order_by('-pub_date')

多個欄位進行排序

比如 對 pub_date 倒序排序,對 headline 正序排序,則是:

Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')

按照外鍵欄位排序

比如 Entry 這個 model 需要按照外鍵 Blog 的 name 欄位來排序,則通過外鍵欄位+雙下劃線+排序欄位來實現:

Entry.objects.order_by('blog__name')

如果我們在查詢 Entry 的時候直接根據外鍵欄位,也就是 blog 來排序,Django 會使用 Blog,也就是外鍵的預設排序(即在 Blog 的 model 的 Meta 里設置的 ordering 來排序),如果外鍵沒有定義預設排序,則會根據主鍵 id 來排序。

比如說,我們的 Blog model,如果沒有在 Meta 里設置預設的 ordering,那麼,下麵的語句:

Entry.objects.order_by('blog')

則會等價於:

Entry.objects.order_by('blog_id')

如果在 Blog 的 model 的 Meta 里有設置 ordering=['name'],那麼則等價於:

Entry.objects.order_by('blog__name')

查詢表達式調用 asc() 或者 desc() 方法:

Entry.objects.order_by(Coalesce('summary', 'headline').desc())

asc() 和 desc() 有 nulls_first 和 nulls_last 來控制 null 如何被排序,是放在最開始還是最後面。

忽略大小寫排序

我們可以通過對欄位進行小寫處理來達到忽略大小寫排序的目的:

Entry.objects.order_by(Lower('headline').desc())

不排序

如果是不想對數據進行任何排序,則可以直接調用 order_by() 函數,不添加任何參數即可。

Entry.objects.order_by()

不支持鏈式處理

需要註意的是,不同於 filter() 函數的鏈式操作,order_by() 是不支持鏈式操作的,每添加一次 order_by(),前面的排序都會被後面的覆蓋。

Entry.objects.order_by('headline').order_by('pub_date')

以上語句則僅會根據 pub_date 進行排序,headline 的排序則會被忽略。

這個功能如果要驗證,很簡答,只需要列印出上述語句轉換成的 SQL 語句即可。

如果查看 Django 的 QuerySet 轉換的 SQL 代碼,以前寫過一篇博客,可以參考:https://blog.csdn.net/weixin_43354181/article/details/102881471

以上就是本篇筆記全部內容,接下來將要介紹的是 reverse、distinct、values、values_list 等用法。

本文首發於本人微信公眾號:Django筆記。

原文鏈接:Django筆記九之model查詢filter、exclude、annotate、order_by

如果想獲取更多相關文章,可掃碼關註閱讀:
image


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 使用 VLD 記憶體泄漏檢測工具輔助開發時整理的學習筆記。本篇介紹 VLD 配置文件中配置項 MaxDataDump 的使用方法。 ...
  • 在現在的日常開發中,不管前端還是後端,JSON 格式的數據是用得比較多的,甚至可以說無處不在。在某些業務場景下也是需要用到 JSON 的,特別是 JSON 與 Java 對象之間的轉化。 ...
  • 本文已經收錄到Github倉庫,該倉庫包含電腦基礎、Java基礎、多線程、JVM、資料庫、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分散式、微服務、設計模式、架構、校招社招分享等核心知識點,歡迎star~ Github地址 今天來熟悉一下,關於JVM調優常 ...
  • 一.去除0的方法 BigDecimal是處理高精度的浮點數運算的常用的一個類 當需要將BigDecimal中保存的浮點數值列印出來,特別是在頁面上顯示的時候,就有可能遇到預想之外的科學技術法表示的問題。 一般直接使用 BigDecimal.toString()方法即可以完成浮點數的列印。 如: Sy ...
  • 使用 VLD 記憶體泄漏檢測工具輔助開發時整理的學習筆記。本篇介紹 VLD 配置文件中配置項 ForceIncludeModules 的使用方法。 ...
  • sychronized是java多線程非常關鍵的一個知識點,這篇博客將從synchronized幾個用法以及代碼來學習。 sychronized的作用是能夠保證同一時間只有一個線程來運行這塊代碼,達到併發效果,如果沒有保證併發的話,在多線程編碼中就會產生致命問題,比如經典的i++,這也是資料庫併發中 ...
  • 使用 VLD 記憶體泄漏檢測工具輔助開發時整理的學習筆記。本篇介紹 VLD 配置文件中配置項 AggregateDuplicates 的使用方法。 ...
  • 本篇將對 Yarn 調度器中的資源搶占方式進行探究。分析當集群資源不足時,占用量資源少的隊列,是如何從其他隊列中搶奪資源的。我們將深入源碼,一步步分析搶奪資源的具體邏輯。 ...
一周排行
    -Advertisement-
    Play Games
  • 基於.NET Framework 4.8 開發的深度學習模型部署測試平臺,提供了YOLO框架的主流系列模型,包括YOLOv8~v9,以及其系列下的Det、Seg、Pose、Obb、Cls等應用場景,同時支持圖像與視頻檢測。模型部署引擎使用的是OpenVINO™、TensorRT、ONNX runti... ...
  • 十年沉澱,重啟開發之路 十年前,我沉浸在開發的海洋中,每日與代碼為伍,與演算法共舞。那時的我,滿懷激情,對技術的追求近乎狂熱。然而,隨著歲月的流逝,生活的忙碌逐漸占據了我的大部分時間,讓我無暇顧及技術的沉澱與積累。 十年間,我經歷了職業生涯的起伏和變遷。從初出茅廬的菜鳥到逐漸嶄露頭角的開發者,我見證了 ...
  • C# 是一種簡單、現代、面向對象和類型安全的編程語言。.NET 是由 Microsoft 創建的開發平臺,平臺包含了語言規範、工具、運行,支持開發各種應用,如Web、移動、桌面等。.NET框架有多個實現,如.NET Framework、.NET Core(及後續的.NET 5+版本),以及社區版本M... ...
  • 前言 本文介紹瞭如何使用三菱提供的MX Component插件實現對三菱PLC軟元件數據的讀寫,記錄了使用電腦模擬,模擬PLC,直至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1. PLC開發編程環境GX Works2,GX Works2下載鏈接 https:// ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • 1、jQuery介紹 jQuery是什麼 jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝 ...
  • 前言 之前的文章把js引擎(aardio封裝庫) 微軟開源的js引擎(ChakraCore))寫好了,這篇文章整點js代碼來測一下bug。測試網站:https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻譯js逆向(MD5加密,AES加密)附完整源碼 ...
  • 引言 現代的操作系統(Windows,Linux,Mac OS)等都可以同時打開多個軟體(任務),這些軟體在我們的感知上是同時運行的,例如我們可以一邊瀏覽網頁,一邊聽音樂。而CPU執行代碼同一時間只能執行一條,但即使我們的電腦是單核CPU也可以同時運行多個任務,如下圖所示,這是因為我們的 CPU 的 ...
  • 掌握使用Python進行文本英文統計的基本方法,並瞭解如何進一步優化和擴展這些方法,以應對更複雜的文本分析任務。 ...
  • 背景 Redis多數據源常見的場景: 分區數據處理:當數據量增長時,單個Redis實例可能無法處理所有的數據。通過使用多個Redis數據源,可以將數據分區存儲在不同的實例中,使得數據處理更加高效。 多租戶應用程式:對於多租戶應用程式,每個租戶可以擁有自己的Redis數據源,以確保數據隔離和安全性。 ...