前言上两篇基本完成的DjangoORM的各种操作,如何检查,各种检查。有兴趣的朋友可以戳这两篇文章学习,一篇带你了解DjangoORM操作(高级),一篇带你了解DjangoORM操作(基础)。但是还有一些技能遗留下来,我们再来看看吧!Queryaggregationoperation聚合操作,别被名字吓到了,一般用在过滤一些数据后求平均值什么的。例如:求所有图书的总价和平均价NativesqlSELECTSUM(price)AS"所有图书的总价",avg(price)AS"所有图书的平均价"FROMweb_book;TSUM(price)AS"所有书籍的总价",avg(price)AS"所有书籍的平均价格"FROMweb_book;执行结果ORMprice=models.Book.objects.all().aggregate(Sum("price"),Avg("price"),)print(price)执行结果可以发现和上面一样,但是会发现列名默认是字段__聚合函数名。原生sql可以指定显示的列名,ORM也可以。代码#需要导入的包django.db.modelsimportAvg,Sumprice=models.Book.objects.all().aggregate(所有书籍的总价=Sum("price"),所有书籍的平均价格=Avg("price"),)print(price)执行结果注:price的类型直接是dict,所以这里看不到原来的sql。但是上面ORM对应的nativeSQL确实如上,所以这样理解就够了。分组操作分组操作就是对某一列中的相同值进行压缩,然后可以得到压缩后的值的个数。如果压缩的是外键,还可以检索到外键的详细信息。示例:查询各出版社的出版物数量。通过研究表结构,发现book表中记录了每一本出版的书,每本书都会有一个publisherid的外键。如果我们可以压缩publisherid,那么在压缩后的publisherid中找出对应的数量。啧啧,这不是出来了吗?代码django.db.modelsimportCountret=models.Book.objects.values("publish_id").annotate(publish_count=Count("publish_id"))print(ret)执行结果nativesqlSELECT`web_book`.`publish_id`,COUNT(`web_book`.`publish_id`)AS`publish_count`FROM`web_book`GROUPBY`web_book`.`publish_id`;ORM分组和原生SQL对应关系图,我记得有一段时间我很迷茫,主要是不知道怎么和原生SQL对应。根据多次测试经验,对应图如下。分组获取外键字段信息以上功能确实可以通过分组来实现。但是上面只能获取publisherid,不能获取publishername,但是如何获取压缩外键字段的详细信息呢?代码ret=models.Book.objects.values("publish_id").annotate(publish_count=Count("publish_id")).values("publish__title","publish__phone","publish_count")print(ret)执行结果注:值后跟分组(注释)。里面只能写外键字段的列和annotate中的列,其他的不能写。如果分组不是外键字段,那么后面就不能再跟值了!分组和过滤。分组过滤的本质是原生SQL的groupby..having,压缩后的数据用于条件判断。但是判断压缩后的数据只能通过having来完成。例子:查询出版社出版的2本以上图书的数据。代码ret=models.Book.objects.values("publish_id")\.annotate(publish_count=Count("publish_id"))\.filter(publish_count__gt=2)print(ret)executeresultFquery有时候,我们可能会有这样的一个要求是在两列之间进行比较。比如经典问题,一个产品,求出比较收藏数量大于销量的产品等两列的需求。示例:查询图书表,评论数小于收藏数。代码来自django.db.modelsimportFbook=models.Book.objects.filter(comment_num__lt=F("collect_num"))print(book)实际结果执行结果F对象也支持加减乘除比较示例:评论数小于两倍的数据采集数量。代码可以是*,or-,+,÷fromdjango.db.modelsimportFbook=models.Book.objects.filter(comment_num__lt=F("collect_num")*2)print(book)执行结果F对象也适用更新代码models.Book.objects.all().update(price=F("price")+30)Qquery通常,我们使用的过滤器(条件1,条件2,...)被执行并查询。但通常有时,我们需要执行或查询。比如在book表中查询title=<<大明帝国>>或者title=<<安史之乱>>。这时候如果使用DjangoORM,只能使用Q查询来构建条件。代码来自django.db.modelsimportQbooks=models.Book.objects.filter(Q(title="<<大明帝国>>")|Q(title="<<安史之乱>>"))print(books)执行结果注释:|表示或,&表示和。因此,如果以上|换成&,filter(condition1,condition2,...)表示and。Q查询的~~相当于not。示例:querytitle="<
