美文网首页
07.模型详解 -- 查询函数

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

作者: __深蓝__ | 来源:发表于2019-03-09 14:05 被阅读0次

    添加测试数据

    • 在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.模型详解 -- 查询函数

          本文链接:https://www.haomeiwen.com/subject/alrspqtx.html