Django框架学习 — 7.2模型详解 -- 查询函数

添加测试数据

在SQLyog中执行

INSERT INTO app_bookinfo(title,bpub_date,bread,bcomment,isDelete) VALUES
('三国演义','1980-5-1',12,34,0),
('红楼梦','1986-7-24',36,40,0),
('水浒传','1995-12-24',20,80,0),
('西游记','1987-11-11',58,24,0);
INSERT INTO app_personinfo(pname,pgender,pcomment,isDelete) VALUES
('曹操',1,'字孟德',0),
('刘备',1,'字玄德',0),
('诸葛亮',1,'字孔明',0),
('孙权',1,'字仲谋',0),
('贾宝玉',1,'荣国府公子',0),
('林黛玉',0,'金陵十二钗之冠',0),
('薛宝钗',0,'薛姨妈之女',0),
('王熙凤',0,'贾琏之妻',0),
('贾母',0,'宝玉祖母',0),
('宋江',1,'呼保义',0),
('卢俊义',1,'玉麒麟',0),
('吴用',1,'智多星',0),
('公孙胜',1,'入云龙',0),
('孙悟空',1,'唐僧的大徒弟',0),
('唐僧',1,'玄奘',0),
('猪八戒',1,'悟能',0),
('沙僧',1,'沙悟净',0);

配置mysql数据库日志

通过日志文件可以查看对数据库的操作记录,mysql默认不产生日志文件,需要进行配置:

手动开启日志
进入mysql命令行:mysql -u root -p
查询日志状态:show variables like ‘general_log%’;
开启日志:set global general_log = ‘on’;

自动开启日志
打开mysql配置文件my.ini,路径是C:\ProgramData\MySQL\MySQL Server 8.0
将general-log的值修改为1
在这里插入图片描述
重启mysql服务

下载、安装baretail.exe工具

在baretail.exe中打开日志文件,
文件位置:C:\ProgramData\MySQL\MySQL Server 8.0\Data中

在linux中使用tail -f 日志文件,监控日志的变化

查询函数

通过模型类.objects属性可以调用如下函数,实现对模型类对应的数据表的查询。
在这里插入图片描述
说明:
all函数以‘查询集’的形式返回所有数据表中的记录,该操作不会立限执行
只有使用了查询集中的数据时才会执行查询
在这里插入图片描述
在这里插入图片描述

实例演练

get函数示例:查询图书id为3的图书信息

def ind![在这里插入图片描述](https://img-blog.csdnimg.cn/20200212214513340.png)ex(request):
    list = BookInfo.objects.get(id=3)
    print(list.id, list.btitle, list.bpub_date, list.bread, list.bcomment)
    return render(request, 'app/index.html')

在这里插入图片描述
all函数示例:查询图书所有信息

def index(request):
    list = BookInfo.objects.get(id=3)
    print(list.id, list.btitle, list.bpub_date, list.bread, list.bcomment)
    return render(request, 'app/index.html')

在这里插入图片描述

条件查询

在Django中,通过调用过滤器filter()、exclude()、get()等实现SQL中的where子句

语法格式: 属性名称__比较运算符 = 值

说明:
属性名称和比较运算符间使用 两个下划线
通过"属性名_id"表示外键对应对象的id值。

条件运算符

修改views.py文件,在index视图中编写如下查询代码:

等值查询
exact:表示判等

例:查询编号为1的图书
list=BookInfo.objects.filter(id__exact=1)
可简写为:
list=BookInfo.objects.filter(id=1)
def index(request):
    list = BookInfo.objects.filter(id__exact=1)

    for book in list:
        print(book.btitle, book.bpub_date)

    return render(request, 'app/index.html')

模糊查询
contains:是否包含
说明:如果要包含%无需转义,直接写即可。

例:查询书名包含'传'的图书
list = BookInfo.objects.filter(btitle__contains='传')

startswith、endswith:以指定值开头或结尾。

例:查询书名以'梦'结尾的图书
list = BookInfo.objects.filter(btitle__endswith='梦')

以上运算符都区分大小写,在这些运算符前加上i表示不区分大小写,如iexact、icontains、istartswith、iendswith.

空查询
isnull:是否为null。

例:查询书名不为空的图书。
list = BookInfo.objects.filter(btitle__isnull=False)

范围查询
in:是否包含在范围内。

例:查询编号为135的图书
list = BookInfo.objects.filter(id__in=[1, 3, 5])

比较查询
gt、gte、lt、lte:大于、大于等于、小于、小于等于。
注意:参数中不能使用等号之外的比较符号
BookInfo.objects.filter(id > 3) 这种写法是错误的

例:查询编号大于3的图书
list = BookInfo.objects.filter(id__gt=3)

不等于的运算符,使用exclude()过滤器。

例:查询编号不等于3的图书
list = BookInfo.objects.exclude(id=3)

日期查询
year、month、day、week_day、hour、minute、second:对日期时间类型的属性进行运算。

例:查询1980年发表的图书。
list = BookInfo.objects.filter(bpub_date__year=1980)
例:查询198011日后发表的图书。
list = BookInfo.objects.filter(bpub_date__gt=date(1990, 1, 1))

F对象
之前的查询都是属性与常量值比较,如果是两个属性比较,可以通过F对象进行
F对象被定义在django.db.models中
语法格式:F(属性名)

例:查询阅读量大于等于评论量的图书。
from django.db.models import F
list = BookInfo.objects.filter(bread__gte=F('bcomment'))

可以在F对象上使用算数运算。

例:查询阅读量大于等于评论量的图书。
from django.db.models import F
list = BookInfo.objects.filter(bread__gte=F('bcomment'))

Q对象
多个过滤器逐个调用表示逻辑与关系,相当于where子句的AND关键字。

例:查询阅读量大于20,并且编号小于3的图书。
list=BookInfo.objects.filter(bread__gt=20,id__lt=3)list=BookInfo.objects.filter(bread__gt=20).filter(id__lt=3)

如果需要实现逻辑或(OR)查询,需要使用Q()对象结合 | 运算符,
Q对象被义在django.db.models中。

语法格式:Q( 属性名__运算符 = 值 )

例:查询阅读量大于20的图书,改写为Q对象如下。
from django.db.models import Q
list = BookInfo.objects.filter(Q(bread__gt=20))

Q对象可以使用&、|连接,&表示逻辑与,|表示逻辑或。

例:查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现
list = BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3))

Q对象前可以使用~操作符,表示非not。

例:查询编号不等于3的图书。
list = BookInfo.objects.filter(~Q(pk=3))

聚合函数

使用aggregate()函数调用聚合函数。
聚合函数包括:Avg,Count,Max,Min,Sum,被定义在django.db.models中

aggregate()返回一个字典类型,格式为{’ 属性名小写__聚合函数名小写 ’ :值},例如:{‘bread__sum’:3}

例:查询图书的总阅读量。
from django.db.models import Sum
def index(request):
    s = BookInfo.objects.aggregate(Sum('bread'))
    print(s['bread__sum'])
    return render(request, 'app/index.html')

count函数返回一个数字,一般不使用aggregate()过滤器。

例:查询图书总数。
c = BookInfo.objects.count()

查询集(QuerySet)

查询集表示从数据库中获取的对象集合,在管理器上调用某些过滤器方法会返回查询集,查询集可以含有零个、一个或多个过滤器。过滤器基于所给的参数限制查询的结果,从Sql的角度,查询集和select语句等价,过滤器像where和limit子句。

返回查询集的过滤器如下:

all():返回所有数据。
filter():返回满足条件的数据。
exclude():返回满足条件之外的数据,相当于sql语句中where部分的not关键字。
order_by():对结果进行排序。
返回单个值的过滤器如下:

get():返回单个满足条件的对象
如果未找到会引发"模型类.DoesNotExist"异常。
如果多条被返回,会引发"模型类.MultipleObjectsReturned"异常。
count():返回当前查询结果的总条数。
aggregate():聚合,返回一个字典。
判断某一个查询集中是否有数据:

exists():判断查询集中是否有数据,如果有则返回True,没有则返回False。
两大特性

惰性执行:创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用。
缓存:使用同一个查询集,第一次使用时会发生数据库的查询,然后把结果缓存下来,再次使用这个查询集时会使用缓存的数据。
示例:查询所有,编辑booktest/views.py的index视图,运行查看。

list=BookInfo.objects.all()

查询集的缓存

每个查询集都包含一个缓存来最小化对数据库的访问。

在新建的查询集中,缓存为空,首次对查询集求值时,会发生数据库查询,django会将查询的结果存在查询集的缓存中,并返回请求的结果,接下来对查询集求值将重用缓存中的结果。

如下是两个查询集,无法重用缓存,每次查询都会与数据库进行一次交互,产生2条SQL语句,增加了数据库的负载。

from booktest.models import BookInfo
[book.id for book in BookInfo.objects.all()]
[book.id for book in BookInfo.objects.all()]

在这里插入图片描述
在这里插入图片描述
经过存储后,可以重用查询集,只产生1条SQL语句,第二次使用缓存中的数据。

list=BookInfo.objects.all()
[book.id for book in list]
[book.id for book in list]

在这里插入图片描述
在这里插入图片描述
限制查询集 (LIMIT子句)

可以对查询集进行取下标或切片操作,等同于sql中的limit和offset子句,对查询集进行切片后返回一个新的查询集,不会立即执行查询

注意:不支持负数索引。

获取一个对象,直接使用[0],等同于[0:1].get(),
[0]如果没有数据,引发IndexError异常,
[0:1].get()如果没有数据,引发DoesNotExist异常。

示例:获取第1、2项,运行查看。

list=BookInfo.objects.all()[0:2]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值