1. 程式人生 > >Django模型層之欄位查詢引數及聚合函式

Django模型層之欄位查詢引數及聚合函式

該系列教程繫個人原創,並完整發布在個人官網劉江的部落格和教程

所有轉載本文者,需在頂部顯著位置註明原作者及www.liujiangblog.com官網地址。

欄位查詢是指如何指定SQL WHERE子句的內容。它們用作QuerySet的filter(), exclude()和get()方法的關鍵字引數。

預設查詢型別為exact。

下表列出了所有的欄位查詢引數:

欄位名 說明
exact 精確匹配
iexact 不區分大小寫的精確匹配
contains 包含匹配
icontains 不區分大小寫的包含匹配
in 在..之內的匹配
gt 大於
gte 大於等於
lt 小於
lte 小於等於
startswith 從開頭匹配
istartswith 不區分大小寫從開頭匹配
endswith 從結尾處匹配
iendswith 不區分大小寫從結尾處匹配
range 範圍匹配
date 日期匹配
year 年份
month 月份
day 日期
week 第幾周
week_day 周幾
time 時間
hour 小時
minute 分鐘
second
isnull 判斷是否為空
search 1.10中被廢棄
regex 區分大小寫的正則匹配
iregex 不區分大小寫的正則匹配

1. exact

精確匹配。 預設的查詢型別!

Entry.objects.get(id__exact=14)
Entry.objects.get(id__exact=None)

2. iexact

不區分大小寫的精確匹配。

Blog.objects.get(name__iexact='beatles blog')
Blog.objects.get(name__iexact=None)

第一個查詢將匹配 'Beatles Blog', 'beatles blog', 'BeAtLes BLoG'等等。

3. contains

大小寫敏感的包含關係匹配。

Entry.objects.get(headline__contains='Lennon')

這將匹配標題'Lennon honored today',但不匹配'lennon honored today'。

4. icontains

不區分大小寫的包含關係匹配。

Entry.objects.get(headline__icontains='Lennon')

5. in

在給定的列表裡查詢。

Entry.objects.filter(id__in=[1, 3, 4])

還可以使用動態查詢集,而不是提供文字值列表:

inner_qs = Blog.objects.filter(name__contains='Cheddar')
entries = Entry.objects.filter(blog__in=inner_qs)

或者從values()或values_list()中獲取的QuerySet作為比對的物件:

inner_qs = Blog.objects.filter(name__contains='Ch').values('name')
entries = Entry.objects.filter(blog__name__in=inner_qs)

下面的例子將產生一個異常,因為試圖提取兩個欄位的值,但是查詢語句只需要一個欄位的值:

# 錯誤的例項,將彈出異常。
inner_qs = Blog.objects.filter(name__contains='Ch').values('name', 'id')
entries = Entry.objects.filter(blog__name__in=inner_qs)

6. gt

大於

Entry.objects.filter(id__gt=4)

7. gte

大於或等於

8. lt

小於

9. lte

小於或等於

10. startswith

區分大小寫,從開始位置匹配。

Entry.objects.filter(headline__startswith='Lennon')

11. istartswith

不區分大小寫,從開始位置匹配。

Entry.objects.filter(headline__istartswith='Lennon')

12. endswith

區分大小寫,從結束未知開始匹配。

Entry.objects.filter(headline__endswith='Lennon')

13. iendswith

不區分大小寫,從結束未知開始匹配。

Entry.objects.filter(headline__iendswith='Lennon')

14. range

範圍測試(包含於之中)。

import datetime
start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))

警告:過濾具有日期的DateTimeField不會包含最後一天,因為邊界被解釋為“給定日期的0am”。

15. date

進行日期對比。

Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

USE_TZ為True時,欄位將轉換為當前時區,然後進行過濾。

16. year

對年份進行匹配。

Entry.objects.filter(pub_date__year=2005)
Entry.objects.filter(pub_date__year__gte=2005)

USE_TZ為True時,在過濾之前,datetime欄位將轉換為當前時區。

17. month

對月份進行匹配。取整數1(1月)至12(12月)。

Entry.objects.filter(pub_date__month=12)
Entry.objects.filter(pub_date__month__gte=6)

當USE_TZ為True時,在過濾之前,datetime欄位將轉換為當前時區。

18. day

對具體到某一天的匹配。

Entry.objects.filter(pub_date__day=3)
Entry.objects.filter(pub_date__day__gte=3)

當USE_TZ為True時,在過濾之前,datetime欄位將轉換為當前時區。

19. week

Django1.11中的新功能。根據ISO-8601返回周號(1-52或53),即星期一開始的星期,星期四或之前的第一週。

Entry.objects.filter(pub_date__week=52)
Entry.objects.filter(pub_date__week__gte=32, pub_date__week__lte=38)

當USE_TZ為True時,欄位將轉換為當前時區,然後進行過濾。

20. week_day

進行“星期幾”匹配。 取整數值,星期日為1,星期一為2,星期六為7。

Entry.objects.filter(pub_date__week_day=2)
Entry.objects.filter(pub_date__week_day__gte=2)

當USE_TZ為True時,在過濾之前,datetime欄位將轉換為當前時區。

21. time

Django1.11中的新功能。

將欄位的值轉為datetime.time格式並進行對比。

Entry.objects.filter(pub_date__time=datetime.time(14, 30))
Entry.objects.filter(pub_date__time__between=(datetime.time(8), datetime.time(17)))

USE_TZ為True時,欄位將轉換為當前時區,然後進行過濾。

22. hour

對小時進行匹配。 取0和23之間的整數。

Event.objects.filter(timestamp__hour=23)
Event.objects.filter(time__hour=5)
Event.objects.filter(timestamp__hour__gte=12)

當USE_TZ為True時,值將過濾前轉換為當前時區。

23. minute

對分鐘匹配。取0和59之間的整數。

Event.objects.filter(timestamp__minute=29)
Event.objects.filter(time__minute=46)
Event.objects.filter(timestamp__minute__gte=29)

當USE_TZ為True時,值將被過濾前轉換為當前時區。

24. second

對秒數進行匹配。取0和59之間的整數。

Event.objects.filter(timestamp__second=31)
Event.objects.filter(time__second=2)
Event.objects.filter(timestamp__second__gte=31)

當USE_TZ為True時,值將過濾前轉換為當前時區。

25. isnull

值為False或True, 相當於SQL語句IS NULL和IS NOT NULL.

Entry.objects.filter(pub_date__isnull=True)

自1.10版以來已棄用。

27. regex

區分大小寫的正則表示式匹配。

Entry.objects.get(title__regex=r'^(An?|The) +')

建議使用原始字串(例如,r'foo'而不是'foo')來傳遞正則表示式語法。

28. iregex

不區分大小寫的正則表示式匹配。

Entry.objects.get(title__iregex=r'^(an?|the) +')

聚合函式

Django的django.db.models模組提供以下聚合函式。

1. expression

引用模型欄位的一個字串,或者一個query expression。

2. output_field

用來表示返回值的model field,一個可選的引數。

3. **extra

關鍵字引數可以給聚合函式生成的SQL提供額外的資訊。

4. Avg

class Avg(expression, output_field=FloatField(), **extra)[source]

返回給定表示式的平均值,它必須是數值,除非指定不同的output_field

預設的別名:<field>__avg
返回型別:float(或指定任何output_field的型別)

5. Count

class Count(expression, distinct=False, **extra)[source]

返回與expression相關的物件的個數。

預設的別名:<field>__count
返回型別:int
有一個可選的引數:distinct。如果distinct=True,Count 將只計算唯一的例項。預設值為False。

6. Max

class Max(expression, output_field=None, **extra)[source]

返回expression的最大值。

預設的別名:<field>__max
返回型別:與輸入欄位的型別相同,如果提供則為`output_field`型別

7. Min

class Min(expression, output_field=None, **extra)[source]

返回expression的最小值。

預設的別名:<field>__min
返回型別:與輸入欄位的型別相同,如果提供則為`output_field`型別

8. StdDev

class StdDev(expression, sample=False, **extra)[source]

返回expression的標準差。

預設的別名:<field>__stddev
返回型別:float
有一個可選的引數:sample。預設情況下,返回群體的標準差。如果sample=True,返回樣本的標準差。
SQLite 沒有直接提供StdDev。

9. Sum

class Sum(expression, output_field=None, **extra)[source]

計算expression的所有值的和。

預設的別名:<field>__sum
返回型別:與輸入欄位的型別相同,如果提供則為output_field型別

10. Variance

class Variance(expression, sample=False, **extra)[source]

返回expression的方差。

預設的別名:<field>__variance
返回型別:float
有一個可選的引數:sample。
SQLite 沒有直接提供Variance。