Django字段查找(Field lookups) 您所在的位置:网站首页 django查询指定字段的值 Django字段查找(Field lookups)

Django字段查找(Field lookups)

2023-10-03 03:27| 来源: 网络整理| 查看: 265

在Django中ORM访问数据库查找时,会用到一些带双下划线的操作,类似Entry.objects.filter(id__gt=4)这种。

本文记录了双下划线之后的“方法”的作用和用法。

学习了下官方文档,在这里总结记录下。若有不清晰的,可参考官方文档:Django2.1官方文档

目录

exact

iexact

contains

icontains

in

gt

gte

lt

lte

startswith

istartswith

endswith

iendswith

range

date

year

month

day

week

week_day

quarter(Django2.0新增)

time

hour

minute

second

isnull

regex

iregex

字段查找是指定SQL WHERE子句的内容的方式,他们用在filter(),exclude()和get()这些QuerySet方法。

Django的内置查找如下,也可以编写自定义查找。

exact

为了方便起见,当没有提供查找类型时(比如 Entry.objects.get(id=12) ),查找类型就假定为exact。

精确匹配。如果为匹配提供的值是None,则会被解读为SQL中的NULL值,例如:

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

相当于SQL语句:

SELECT ... WHERE id = 12; SELECT ... WHERE id IS NULL; MySQL 匹配

在MySQL中,数据库表的名为“collation”的设置来确定exact匹配是否区分大小写。 这是一个数据库设置,而不是Django设置。 可以将MySQL表配置为区分大小写,但需要进行一些权衡。 有关这方面的更多信息,查看Collation settings。

 iexact

不区分大小写的精确匹配。例如:

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

相当于SQL语句:

SELECT ... WHERE name ILIKE 'beatles blog'; SELECT ... WHERE name IS NULL;

'Beatles Blog',  'beatles blog', 'BeAtLes BLog'等等都会被上面第一个查询匹配到。

contains

区分大小写的包含匹配。例如:

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

相当于SQL语句:

SELECT ... WHERE headline LIKE '%Lennon%';

这会匹配到‘Lennon honored today’但是不会匹配到‘lennon honored today’。(因为区分大小写)

SQLlite 用户

SQLite不支持区分大小写的 “LIKE”声明,所以对于SQLite来说,contains和icontains是一样的。

icontains

不区分大小写的包含匹配。使用方法见contains。

in

在一个给定的可迭代对象中,通常是一个列表,元组,或queryset,它并不常用,但是接受字符串(可迭代)。例如:

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

相当于SQL语句:

SELECT ... WHERE id IN (1, 3, 4); SELECT ... WHERE headline IN ('a', 'b', 'c');

如果在in操作中传入values()或者value_list()的queryset结果,必须确保这个结果只提取了一个字段。例如:

# 正确操作,只提取了一个“name” inner_qs = Blog.objects.filter(name__contains='Ch').values('name') entries = Entry.objects.filter(blog__name__in=inner_qs) # 错误操作,提取了“name”和“id”两个字段,会抛出TypeError inner_qs = Blog.objects.filter(name__contains='Ch').values('name', 'id') entries = Entry.objects.filter(blog__name__in=inner_qs) 性能考虑:

请谨慎使用嵌套查询并了解数据库服务器的性能特征(如果有疑问,请使用基准测试!)。一些数据库后端,尤其是MySQL,不能很好地优化嵌套查询。在这些情况下,提取值列表然后将其传递到第二个查询更有效。也就是说,执行两个查询而不是一个:

values = Blog.objects.filter( name__contains='Cheddar').values_list('pk', flat=True) entries = Entry.objects.filter(blog__in=list(values))

注意:list()会强制执行第一个查询,没有它,会变成嵌套查询,因为QuerySet是懒惰的。

 gt

Greater than. (大于)

例如:

Entry.objects.filter(id__gt=4) # 即 SELECT ... WHERE id > 4; gte

Greater than or eaual to.(大于等于)

lt

Less than. (小于)

lte

Less than or equal to. (小于等于)

startswith

以。。。开头(区分大小写)

istartswith

以。。。开头(不区分大小写)

endswith

以。。。结尾(区分大小写)

iendswith

以。。。结尾(不区分大小写)

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)) # 相当于SQL SELECT ... WHERE pun_date BETWEEN '2005-01-01' and '2005-03-31';

只要在SQL中能使用BETWEEN的地方,都能使用range——对时间,数字,甚至字符。

Warning!

Filter一个DateTimeField字段会不包括时间范围的最后一天,因为界限被解析为“给定日期的0点”,如果pub_date是一个DateTImeField类型,上面的Python代码翻译成SQL会是:

SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';

也就是说,不能混用date和datetime,他们有差别。

 date

将datetime类型的字段转换为date,允许链接其他字段查找,得到一个date类型的值。例如:

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

(此查找不包含等效的SQL代码片段,因为相关查询的实现因不同的数据库引擎而异。)

当USE_TZ为True时,字段将在筛选之前转换为当前时区。

year

对于date和datetime字段,精确地匹配年份。允许链接其他字段查找,筛选时传入一个int型年份。例如:

Entry.objects.filter(pub_date__year=2005) Entry.objects.filter(pub_date__year__gte=2005) # 相当于SQL SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31'; SELECT ... WHERE pub_date >= '2005-01-01';

(具体的SQL语法取决于具体的数据库引擎。)

当USE_TZ为True时,字段将在筛选之前转换为当前时区。

month

和year作用相同,筛选时传入一个int型月份(1-12)。

Entry.objects.filter(pub_date__month=12) Entry.objects.filter(pub_date__month__gte=6) # 相当于SQL SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12'; SELECT ... WHERE EXTRACT('month' FROM pub_date) >= '6'; day

和year以及month作用相同。

Entry.objects.filter(pub_date__day=3)会筛选出来若干条日期为3的记录,例如一月三号,二月三号等等。

week

对于date和datetime字段,返回周数(1-52 or 53)。

Entry.objects.filter(pub_date__week=52)会筛选出日期为一年中第52周的记录。

week_day

对于date和datetime字段作一个“一周中的哪一天”匹配。

筛选时传入一个int型值代表星期几(1-7, 1代表Sunday,7代表Saturday)。

Entry.objects.filter(pub_date__week_day=2) 这会筛选出所有当天日期是星期一的记录,和月份年份都无关。

quarter(Django2.0新增)

对于date和datetime字段,匹配季度(1-4)。

Entry.objects.filter(pub_date__quarter=2),日期在第二个季度(4月1日至6月30日)的所有记录。

time

将datetime字段转换为time,筛选时传入一个datetime.time值。例如:

# 筛选时间为14:30的记录 Entry.objects.filter(pub_date__time=datetime.time(14, 30)) # 筛选时间在8:00到17:00的记录 Entry.objects.filter(pub_date__time__range=(datetime.time(8), datetime.time(17))) hour

对于datetime和time字段,匹配具体的“时”,筛选时传入一个int型数字(0-23)。

minute

对于datetime和time字段,匹配具体的“时”,筛选时传入一个int型数字(0-59)。

second

对于datetime和time字段,匹配具体的“秒”,筛选时传入一个int型数字(0-59)。

isnull

True或False,分别对应于IS NULL和IS NOT NULL的SQL查询。

regex

区分大小写的正则表达式匹配。

正则表达式的语法取决于正在使用的数据库,例如SQLite,它没有内置的正则表达式支持,这个功能就有用户定义的REGEXP函数提供,并且正则表达式语法和Python的re模块相同。例如:

Entry.objects.get(title__regex=r'^(An?|The) +') # 对应SQL 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

不区分大小写的正则表达式匹配。

以上。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有