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)
26. search
自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。