引言
在之前的 Django模型设计 中简单的介绍了如何利用模型类对数据库进行增删改查,在这篇中主要介绍使用模型类对数据库进行条件查询。让大家更加熟悉
Django
操作数据库。
环境
环境名称 | 版本 |
---|---|
Python | 3.7.9 |
Django | 3.1.2 |
MySql-Server | 5.7.32 |
PyMySQL | 0.10.1 |
数据库表:
以如下数据表数据进行测试:
id | title | author | pub_date | read | comment |
---|---|---|---|---|---|
1 | 天龙八部 | 金庸 | 1967-10-17 | 5000 | 3000 |
2 | 射雕英雄传 | 金庸 | 1969-03-17 | 8000 | 5000 |
3 | 神雕侠侣 | 金庸 | 1959-10-17 | 6000 | 8000 |
4 | 三少爷的剑 | 古龙 | 1977-08-01 | 3000 | 1000 |
5 | 笑傲江湖 | 金庸 | 1969-03-17 | 7000 | 9000 |
字段查询
实现 sql
中 where
的功能,调用过滤器 filter()
、exclude()
、get()
,下面以filter()
为例。
通过 属性名_id
表示外键对应对象的 id
值。
语法如下:
代码语言:javascript复制属性名称__比较运算符=值
说明:属性名称和比较运算符间使用两个下划线,所以属性名不能包括多个下划线。
1) 查询等
exact:表示判等。
例:查询编号为1的图书。
代码语言:javascript复制book = BookInfo.objects.filter(id__exact=1)
可简写为:
book = BookInfo.objects.filter(id=1)
2) 模糊查询
contains:是否包含。
说明:如果要包含%无需转义,直接写即可。
例:查询书名包含 传
的图书。
books = BookInfo.objects.filter(title__contains='传')
startswith、endswith:以指定值开头或结尾。
例:查询书名以’部’结尾的图书
代码语言:javascript复制books = BookInfo.objects.filter(title__endswith='部')
以上运算符都区分大小写,在这些运算符前加上
i
表示不区分大小写 如 iexact、icontains、istartswith、iendswith.
3) 空查询
isnull:是否为null。
例:查询书名不为空的图书。
代码语言:javascript复制books = BookInfo.objects.filter(title__isnull=False)
4) 范围查询
in:是否包含在范围内。
例:查询编号为1或3或5的图书
代码语言:javascript复制books = BookInfo.objects.filter(id__in=[1, 3, 5])
5) 比较查询
gt、gte、lt、lte:大于、大于等于、小于、小于等于。
名称 | 全称 | 含义 |
---|---|---|
gt | greater than | 大于 |
gte | greater than equal | 大于等于 |
lt | less than | 小于 |
lte | less than | 小于等于 |
全称更方便理解记忆。
例:查询编号大于3的图书
代码语言:javascript复制books = BookInfo.objects.filter(id__gt=3)
不等于的运算符,使用exclude()过滤器。
例:查询编号不等于3的图书
代码语言:javascript复制books = BookInfo.objects.exclude(id=3)
6) 日期查询
year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。
例:查询1969年发表的图书。
代码语言:javascript复制books = BookInfo.objects.filter(pub_date__year=1969)
例:查询1960年1月1日后发表的图书。
代码语言:javascript复制books = BookInfo.objects.filter(pub_date__gt=date(1960, 1, 1))
F对象
之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢?
答:使用 F对象
,被定义在 django.db.models
中。
语法如下:
代码语言:javascript复制F(属性名)
例:查询阅读量大于等于评论量的图书。
代码语言:javascript复制from django.db.models import F
...
books = BookInfo.objects.filter(read__gte=F('comment'))
可以在F对象上使用算数运算。
例:查询阅读量大于2倍评论量的图书。
代码语言:javascript复制books = BookInfo.objects.filter(read__gt=F('comment') * 2)
Q对象
多个过滤器逐个调用表示逻辑与关系,同 sql语句
中 where
部分的 and
关键字。
例:查询阅读量大于20,并且编号小于3的图书。
代码语言:javascript复制books = BookInfo.objects.filter(read__gt=20, id__lt=3)
或
books = BookInfo.objects.filter(read__gt=20).filter(id__lt=3)
如果需要实现 逻辑或or
的查询,需要使用 Q对象
结合 |
运算符,Q对象
被定义在 django.db.models
中。
语法如下:
代码语言:javascript复制Q(属性名__运算符=值)
例:查询阅读量大于5000的图书,改写为Q对象如下。
代码语言:javascript复制from django.db.models import Q
...
books = BookInfo.objects.filter(read__gt=5000)
改写成Q对象
books = BookInfo.objects.filter(Q(read__gt=5000))
Q对象
可以使用 &
、|
连接,&
表示逻辑与,|
表示逻辑或。
例:查询阅读量大于5000,或编号小于3的图书,只能使用Q对象实现
代码语言:javascript复制books = BookInfo.objects.filter(Q(read__gt=5000) | Q(pk__lt=3))
Q对象前可以使用 ~
操作符,表示非、not
。
例:查询编号不等于3的图书。
代码语言:javascript复制books = BookInfo.objects.filter(~Q(pk=3))
注意:pk,全称 primary key 代表主键 id
聚合函数
使用 aggregate()
过滤器调用聚合函数。聚合函数包括:Avg、Count、Max、Min、Sum
,被定义在django.db.models
中。
例:查询图书的总阅读量。
代码语言:javascript复制from django.db.models import Sum
...
books = BookInfo.objects.aggregate(Sum('read'))
注意:aggregate 的返回值是一个字典类型,格式如下:
代码语言:javascript复制{'聚合类小写__属性名':值}
如:
{'sum__read': 29000}
使用 count
时一般不使用 aggregate()
过滤器。
例:查询图书总数。
代码语言:javascript复制books = BookInfo.objects.count()
注意:count函数的返回值是一个数字。
公众号
新建文件夹X
大自然用数百亿年创造出我们现实世界,而程序员用几百年创造出一个完全不同的虚拟世界。我们用键盘敲出一砖一瓦,用大脑构建一切。人们把1000视为权威,我们反其道行之,捍卫1024的地位。我们不是键盘侠,我们只是平凡世界中不凡的缔造者 。