Django筆記十四之統計總數、最新紀錄和空值判斷等功能

XHunter發表於2023-04-02

本篇筆記將介紹一些 Django 查詢中統計總數、最新紀錄和空值判斷等功能。

  1. count
  2. in_bulk
  3. latest、earliest
  4. first、last
  5. exists
  6. contains、icontains
  7. gt、gte、lt、lte
  8. startswith、istartswith
  9. isnull

1、count

返回查詢的 QuerySet 的總數。

比如想查詢 Blog 下 name = 'hunter' 的總數:

Blog.objects.filter(name="hunter").count()

返回的結果直接是一個整數,類似的 SQL 程式碼如下:

select count(*) from blog_blog where name = 'hunter';

2、in_bluk

返回一個 dict,key 為我們指定的欄位名的值,value 為這個欄位名所在 object 資料。

比如我們需要查詢 Blog 這個 model 下 name 為 "hunter", "jack" 的資料,可以如下實現:

Blog.objects.in_bulk(["hunter", "jack"], field_name="name")

返回的資料如下:

{'hunter': <Blog: Blog object (1)>, 'jack': <Blog: Blog object (2)>}

但是需要注意,field_name 這個欄位必須有唯一鍵的約束,即:

class Blog(models.Model):
    name = models.CharField(max_length=100, unique=True)
    tagline = models.TextField()

不指定 field_name
如果不指定 field_name 的值的話,那麼則會預設第一個引數列表的 value 值為 id:

Blog.objects.in_bulk([1, 2])

{1: <Blog: Blog object (1)>, 2: <Blog: Blog object (2)>}

不傳引數

如果函式里不傳引數,則預設以 field_name="id" 返回所有資料:

Blog.objects.in_bulk()

引數為空

如果函式里的引數為空,則返回空:

Blog.objects.in_bulk([])

3、latest、earliest

latest() 和 earliest() 一樣,都是按照指定欄位排序後返回最新的,或者最早的一條資料,返回的是 model 的一個例項。

前面介紹在 model 的 Meta 裡如果給 get_latest_by 指定了欄位,那麼 latest() 就可以不加引數,預設按照 get_latest_by 的引數進行排序獲取資料。

否則必須在 latest() 裡指定欄位。

用法如下:

entry_obj = Entry.objects.latest('pub_date)

entry_obj = Entry.objects.latest('pub_date', '-expire_date')

系統會按照 pub_date 欄位進行排序,然後返回最近的一條資料。

注意:這個操作和 get() 方法一樣,如果表裡不存在資料,使用 latest() 函式就會報錯。

處理 null 值
不同的資料庫對 null 值的處理是不一樣的,mysql 對 null 的排序會比非null值更高,

所以,在 mysql 中如果想排除掉 null 值,可以在 filter() 中去除這些資料:

Entry.objects.filter(pub_date__isnull=False).latest('pub_date')

latest() 是返回最新的一條資料

earliest() 則是返回最舊的一條資料。

4、first、last

返回符合條件的第一條資料:

Entry.objects.first()

也可以加上filter 和 排序條件:

entry = Entry.objects.filter(id__gte=12).order_by("pub_date").first()

注意: 如果沒有符合條件的資料,返回的結果可能是 None

last() 則是返回最後一條資料。

5、exists

檢測資料是否存在,返回布林型結果。


is_exist = Blog.objects.filter(id=1).exists()

判斷某種條件的資料是否存在,可以使用這種方式查詢。

查詢的結果可以有多個,只要結果數 >= 1,返回即為 True。

6、contains、icontains

contains 意思為包含指定字串,用法如下:

Blog.objects.filter(name__contains="hunter")

對應的 SQL 為:

select * from blog_blog where name like binary '%hunter%'

因為 MySQL 中的 like 是忽略大小寫的,所以透過 like binary 來強制不忽略大小寫。

而 icontains 的含義和 contains 一致,不過是忽略大小寫的:

Blog.objects.filter(name__icontains="hunter")

上面的語句中,name 欄位內容包含 Hunter、HUNTER、hUnTER 等任何中的都可以被匹配上,
對應的 SQL 為:

select * from blog_blog where name like '%hunter%'

7、gt、gte、lt、lte

gt: greater than,大於
gte: greater than or equal to 大於等於
lt: less than 小於
lte: less than or equal to 小於等於

用法示例如下:

Blog.objects.filter(id__gt=12)

對應的 SQL 為:

select * from blog_blog where id > 12

8、startswith、istartswith

startswith 以指定字串為開頭,跟 python 裡的用法類似

python 用法:

is_right = "abc".startswth("ab")

返回的 is_right 是一個 布林型資料,表示是否以什麼為開頭。

Django 裡的用法是:

Blog.objects.filter(name__startswith="hunter")

返回一個 QuerySet,對應的 SQL 是:

select * from blog_blog where name like binary 'hunter%'

startswith 是區分大小寫的,istartswith 則是忽略大小寫的用法

9、isnull

判斷欄位值是否為 null。

比如我們要取出 Enyry 表裡所有 pub_date 欄位為 null 的資料:

Entry.objects.filter(pub_date__isnull=True)

如果是取出所有欄位值不為空的資料:

Entry.objects.filter(pub_date__isnull=False)

以上就是本篇筆記全部內容,下一篇筆記將介紹model 查詢的範圍和日期的篩選功能。

本文首發於本人微信公眾號:Hunter後端

原文連結:Django筆記十四之統計總數、最新紀錄和空值判斷等功能

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

相關文章