Django教程 —— 模型类条件查询

2021-09-29 16:15:18 浏览数 (1)

引言

在之前的 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

字段查询

实现 sqlwhere 的功能,调用过滤器 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:是否包含。

说明:如果要包含%无需转义,直接写即可。

例:查询书名包含 的图书。

代码语言:javascript复制
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的地位。我们不是键盘侠,我们只是平凡世界中不凡的缔造者 。

0 人点赞