07.模型详解 -- 查询函数

添加测试数据

  • 在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属性可以调用如下函数,实现对模型类对应的数据表的查询。

函数名 功能 返回值 说明
get 返回表中满足条件的一条数据,并且只能是一条数据 模型类对象 参数中写查询条件。
1) 查到多条数据抛异常
MultipleObjectsReturned
2) 查询不到数据抛异常
DoesNotExist
all 返回表格中所有数据 QuerySet类型 查询集
filter 返回满足条件的数据 QuerySet类型 参数写查询条件
exclude 返回不满足条件的数据 QuerySet类型 参数写查询条件
order_by 对查询结果进行排序 QuerySet类型 参数中写根据哪些字段进行排序

说明:
all函数以‘查询集’的形式返回所有数据表中的记录,该操作不会立限执行
只有使用了查询集中的数据时才会执行查询

实例演练

  • get函数示例:查询图书id为3的图书信息
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')
  • all函数示例:查询图书所有信息
def index(request):
    list = BookInfo.objects.all()
    for book in list:
        print(book.id, book.btitle, book.bpub_date, book.bread, book.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:是否包含在范围内。
例:查询编号为1或3或5的图书
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)
例:查询1980年1月1日后发表的图书。
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对象上使用算数运算。

例:查询阅读量大于2倍评论量的图书
list = BookInfo.objects.filter(bread__gt=F('bcomment') * 2)
  • 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()函数调用聚合函数。
聚合函数包括:AvgCountMaxMinSum,被定义在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]




- end -

你可能感兴趣的:(07.模型详解 -- 查询函数)