Django Field lookups
Django Field lookups 就是sql语句的where子句的意思,即 QuerySet 的 filter(), exclude() and get()方法。
lookup参数的组成规则如下:
#注意这里是双下划线
field__lookuptype=value
例如
>>> Entry.objects.filter(pub_date__lte='2006-01-01')
意味着
SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';
Django database API 支持2打(24)lookup types。
exact
精确匹配. 如果参数值为 None, 意味这 SQL 的NULL.
Entry.objects.get(id__exact=14)
Entry.objects.get(id__exact=None)
等价于
SELECT ... WHERE id = 14;
SELECT ... WHERE id IS NULL;
如果你没有设置lookuptype(参数名称不包含双下划线),默认的thelookup type就是 exact。exact lookups是最常用的lookuptype。
例如下面就是等价的
>>> Blog.objects.get(id__exact=14) # Explicit form
>>> Blog.objects.get(id=14) # __exact is implied
iexact
大小写不敏感精确匹配. 如果参数值为 None, 意味这 SQL 的NULL.
Blog.objects.get(name__iexact='beatles blog')
Blog.objects.get(name__iexact=None)
等价于
#匹配'Beatles Blog', 'beatles blog', 'BeAtLes BLoG', etc.
SELECT ... WHERE name ILIKE 'beatles blog';
SELECT ... WHERE name IS NULL;
contains
大小写敏感包含
Entry.objects.get(headline__contains='Lennon')
等价
#匹配 'Lennon honored today' 不匹配'lennon honored today'.
SELECT ... WHERE headline LIKE '%Lennon%';
注意:SQLite 不支持大小写敏感的LIKE 子句; contains 和icontains一样。
icontains
大小写不敏感包含
Entry.objects.get(headline__icontains='Lennon')
等价于
SELECT ... WHERE headline ILIKE '%Lennon%';
in
In 可以被赋值iterable; 例如 a list, tuple, or queryset.
Entry.objects.filter(id__in=[1, 3, 4])
Entry.objects.filter(headline__in='abc')
等价于
SELECT ... WHERE id IN (1, 3, 4);
SELECT ... WHERE headline IN ('a', 'b', 'c');
也可以使用queryset动态计算:
inner_qs = Blog.objects.filter(name__contains='Cheddar')
entries = Entry.objects.filter(blog__in=inner_qs)
等价于
SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')
注意 in 只能接受单字段
# Bad code! Will raise a TypeError.
inner_qs = Blog.objects.filter(name__contains='Ch').values('name', 'id')
entries = Entry.objects.filter(blog__name__in=inner_qs)
gt
大于
Entry.objects.filter(id__gt=4)
等价于
SELECT ... WHERE id > 4;
gte
大于等于
lt
小于
lte
小于等于
startswith
大小写敏感starts-with.
Entry.objects.filter(headline__startswith='Lennon')
等价于
SELECT ... WHERE headline LIKE 'Lennon%';
SQLite 不支持大小写敏感的 LIKE 子句; startswith 和istartswith 一样
istartswith
大小写不敏感starts-with.
Entry.objects.filter(headline__istartswith='Lennon')
等价于
SELECT ... WHERE headline ILIKE 'Lennon%';
endswith
大小写敏感ends-with.
Entry.objects.filter(headline__endswith='Lennon')
等价于
SELECT ... WHERE headline LIKE '%Lennon';
SQLite 不支持大小写敏感的 LIKE 子句; endswith 和 iendswith 一样
iendswith
大小写不敏感ends-with.
Entry.objects.filter(headline__iendswith='Lennon')
等价于
SELECT ... WHERE headline ILIKE '%Lennon'
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))
等价于
SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
警告
用DateTimeField 来过滤date类型不会包含最后一天的。因为边界被解释为“给定日期的0am”。 如果pub_date 是 DateTimeField类型字段,上面等价于
SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';
date
对datetime型字段来说, 转为 date.允许链接附加字段查找。获取日期值。
Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
year
对date 和 datetime 类型字段来说, 年精确匹配. 允许链接附加字段查找。获取年份值。
Entry.objects.filter(pub_date__year=2005)
Entry.objects.filter(pub_date__year__gte=2005)
等价于
SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
SELECT ... WHERE pub_date >= '2005-01-01';
month
对date 和 datetime 类型字段来说, 月精确匹配. 允许链接附加字段查找。获取月份值(1~12)。
Entry.objects.filter(pub_date__month=12)
Entry.objects.filter(pub_date__month__gte=6)
等价于
SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12';
SELECT ... WHERE EXTRACT('month' FROM pub_date) >= '6';
day
对date 和 datetime 类型字段来说, 日精确匹配. 允许链接附加字段查找。获取日份值(1~31)。
Entry.objects.filter(pub_date__day=3)
Entry.objects.filter(pub_date__day__gte=3)
等价于
SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3';
SELECT ... WHERE EXTRACT('day' FROM pub_date) >= '3';
week
对date 和 datetime 类型字段来说, 返回依据 ISO-8601的周数(1-52 or 53) , 周开始于星期一,第一周包含一年的第一个星期四。
Entry.objects.filter(pub_date__week=52)
Entry.objects.filter(pub_date__week__gte=32, pub_date__week__lte=38)
week_day
对date 和 datetime 类型字段来说, 一周的几天匹配。允许链接附加字段查找。获取日份值(1~7)
Entry.objects.filter(pub_date__week_day=2)
Entry.objects.filter(pub_date__week_day__gte=2)
quarter
Django 2.0新增
对date 和 datetime 类型字段来说, 一年中的四分之几匹配(四季匹配)允许链接附加字段查找。获取季份值(1~4)
Entry.objects.filter(pub_date__quarter=2)
time
datetime字段,对比时间值。允许链接附加字段查找。取值datetime.time
Entry.objects.filter(pub_date__time=datetime.time(14, 30))
Entry.objects.filter(pub_date__time__range=(datetime.time(8), datetime.time(17)))
hour
对time 和 datetime 类型字段来说, 小时精确匹配 。允许链接附加字段查找。取值(0~23)
Event.objects.filter(timestamp__hour=23)
Event.objects.filter(time__hour=5)
Event.objects.filter(timestamp__hour__gte=12)
SELECT ... WHERE EXTRACT('hour' FROM timestamp) = '23';
SELECT ... WHERE EXTRACT('hour' FROM time) = '5';
SELECT ... WHERE EXTRACT('hour' FROM timestamp) >= '12';
minute
对time 和 datetime 类型字段来说, 分钟精确匹配 。允许链接附加字段查找。取值(0~59)
Event.objects.filter(timestamp__minute=29)
Event.objects.filter(time__minute=46)
Event.objects.filter(timestamp__minute__gte=29)
等价于
SELECT ... WHERE EXTRACT('minute' FROM timestamp) = '29';
SELECT ... WHERE EXTRACT('minute' FROM time) = '46';
SELECT ... WHERE EXTRACT('minute' FROM timestamp) >= '29';
second
对time 和 datetime 类型字段来说, 秒钟精确匹配 。允许链接附加字段查找。取值(0~59)
Event.objects.filter(timestamp__second=31)
Event.objects.filter(time__second=2)
Event.objects.filter(timestamp__second__gte=31)
等价于
SELECT ... WHERE EXTRACT('second' FROM timestamp) = '31';
SELECT ... WHERE EXTRACT('second' FROM time) = '2';
SELECT ... WHERE EXTRACT('second' FROM timestamp) >= '31';
isnull
是否为空
Entry.objects.filter(pub_date__isnull=True)
SELECT ... WHERE pub_date IS NULL;
regex
大小写敏感正则匹配
Entry.objects.get(title__regex=r'^(An?|The) +')
等价于
SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
SELECT ... WHERE REGEXP_LIKE(title, '^(An?|The) +', 'c'); -- Oracle
SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL
SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite
#iregex
大小写不敏感正则匹配
Entry.objects.get(title__iregex=r'^(an?|the) +')
等价于
SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL
SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'i'); -- Oracle
SELECT ... WHERE title ~* '^(an?|the) +'; -- PostgreSQL
SELECT ... WHERE title REGEXP '(?i)^(an?|the) +'; -- SQLite