90.QuerySet API方法使用详解:distinct
distinct:去掉获取的数据中的重复数据,这个方法如果底层使用的数据库是mysql,那么就不能传递任何参数。
(1)比如以下我们想要实现提取所有价格超过80元的图书,并且删掉那些重复的,那么可以使用distinct来帮我们实现,示例代码如下:
# distinct:删除重复的数据
def index11(request):
# 比如,求价格大于80的图书有哪几种
books = Book.objects.filter(bookorder__price__gte=80).distinct()
print(books)
print(connection.queries)
return HttpResponse("success")
# 在不使用distinct()函数进行过滤的时候,会出现重复的图书
<QuerySet [<Book: Book object (1)>, <Book: Book object (2)>, <Book: Book object (2)>, <Book: Book object (3)>]>
[{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'},
{'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'},
{'sql': 'SELECT `book`.`id`, `book`.`name`, `book`.`pages`, `book`.`price`, `book`.`rating`, `book`.`author_id`, `book`.`publisher_id`, `book`.`score` FROM `book` INNER JOIN `book_order` ON (`book`.`id` = `book_order`.`book_id`) WHERE `book_order`.`price` >= 80.0e0 LIMIT 21', 'time': '0.000'}]
# 使用distinct函数删除重复的数据
<QuerySet [<Book: Book object (1)>, <Book: Book object (2)>, <Book: Book object (3)>]>
[{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'},
{'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'},
{'sql': 'SELECT DISTINCT `book`.`id`, `book`.`name`, `book`.`pages`, `book`.`price`, `book`.`rating`, `book`.`author_id`, `book`.`publisher_id`, `book`.`score` FROM `book` INNER JOIN `book_order` ON (`book`.`id` = `book_order`.`book_id`) WHERE `book_order`.`price` >= 80.0e0 LIMIT 21', 'time': '0.000'}]
(2)在查询的时候为book表添加一个字段订单价格,因为订单的价格order_price都不同,因此,即使使用了distinct函数将重复的数据删除,也会因为订单价格order_price的不同,将所有的图书对象都打印出来,示例代码如下:
def index11(request):
# 比如,求价格大于80的图书有哪几种
books = Book.objects.annotate(order_price=F('bookorder__price')).filter(bookorder__price__gte=80).distinct()
print(books)
print(connection.queries)
return HttpResponse("success")
打印出django底层执行的sql语句和查找出来的价格大于80的图书为:
<QuerySet [<Book: Book object (1)>, <Book: Book object (2)>, <Book: Book object (2)>, <Book: Book object (3)>, <Book: Book object (3)>, <Book: Book object (1)>]>
[{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'},
{'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'},
{'sql': 'SELECT DISTINCT `book`.`id`, `book`.`name`, `book`.`pages`, `book`.`price`, `book`.`rating`, `book`.`author_id`, `book`.`publisher_id`, `book`.`score`, `book_order`.`price` AS `order_price` FROM `book` LEFT OUTER JOIN `book_order` ON (`book`.`id` = `book_order`.`book_id`) INNER JOIN `book_order` T3 ON (`book`.`id` = T3.`book_id`) WHERE T3.`price` >= 80.0e0 LIMIT 21', 'time': '0.000'}]
(3)distinct和order_by()链式调用的时候一定要注意,order_by在进行排序的时候同样会使用到book_order.price ASC,所以在从数据库中删选不重复的数据的时候就会提取book_order.price字段的数据,而这个字段的数据又是不相同的,所以就会提取出所有的book_order对象。示例代码如下:
def index11(request):
# 比如,求价格大于80的图书有哪几种
books = Book.objects.filter(bookorder__price__gte=80).order_by('bookorder__price').distinct()
print(books)
print(connection.queries)
return HttpResponse("success")
<QuerySet [<Book: Book object (2)>, <Book: Book object (1)>, <Book: Book object (3)>, <Book: Book object (2)>]>
[{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'},
{'sql': 'SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'},
{'sql': 'SELECT DISTINCT `book`.`id`, `book`.`name`, `book`.`pages`, `book`.`price`, `book`.`rating`, `book`.`author_id`, `book`.`publisher_id`, `book`.`score`, `book_order`.`price` FROM `book` INNER JOIN `book_order` ON (`book`.`id` = `book_order`.`book_id`) WHERE `book_order`.`price` >= 80.0e0 ORDER BY `book_order`.`price` ASC LIMIT 21', 'time': '0.000'}]
90.QuerySet API方法使用详解:distinct的更多相关文章
- 89.QuerySet API常用方法使用详解:count,first,last,aggregate,exists
1.count():计算数据的个数. 计算数据的个数可以使用count,在python中使用len()也可以计算数据的个数,但是相对来说效率没有使用count()效率高,因为在底层是使用select ...
- 2020你还不会Java8新特性?方法引用详解及Stream 流介绍和操作方式详解(三)
方法引用详解 方法引用: method reference 方法引用实际上是Lambda表达式的一种语法糖 我们可以将方法引用看作是一个「函数指针」,function pointer 方法引用共分为4 ...
- jQuery操纵DOM元素属性 attr()和removeAtrr()方法使用详解
jQuery操纵DOM元素属性 attr()和removeAtrr()方法使用详解 jQuery中操纵元素属性的方法: attr(): 读或者写匹配元素的属性值. removeAttr(): 从匹配的 ...
- C#操作SQLite方法实例详解
用 C# 访问 SQLite 入门(1) CC++C#SQLiteFirefox 用 C# 访问 SQLite 入门 (1) SQLite 在 VS C# 环境下的开发,网上已经有很多教程.我也是从 ...
- Underscore _.template 方法使用详解
为什么用「void 0」代替「undefined」 undefined 并不是保留词(reserved word),它只是全局对象的一个属性,在低版本 IE 中能被重写. 事实上,undefined ...
- 精讲RestTemplate第4篇-DELETE、PUT等请求方法使用详解
本文是精讲RestTemplate第5篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...
- CentOS 6.3下Samba服务器的安装与配置方法(图文详解)
这篇文章主要介绍了CentOS 6.3下Samba服务器的安装与配置方法(图文详解),需要的朋友可以参考下 一.简介 Samba是一个能让Linux系统应用Microsoft网络通讯协议的软件, ...
- php课程---Windows.open()方法参数详解
Window.open()方法参数详解 1, 最基本的弹出窗口代码 window.open('page.html'); 2, 经过设置后的弹出窗口 window.open('page.html ...
- Window.open()方法参数详解
Window.open()方法参数详解 1, 最基本的弹出窗口代码 window.open('page.html'); 2, 经过设置后的弹出窗口 window.open('page.html ...
随机推荐
- golang用slice、list当queue
背景 golang没有queue这种类型,不过可以用slice.list模拟 slice当queue 声明队列 var queue []int 入队一个元素: queue = append(queue ...
- Arduino函数
输入输出函数 pinMode(pin, mode)将数位脚位(digital pin)指定为输入或输出.如:pinMode(7,INPUT); // 将脚位 7 设定为输入模式 digitalWrit ...
- java核心-JVM-gc面试题
1.写一个memory leak的例子 public class MemonyLeak { //1.memoryLeak内存泄漏 /* 这类错误报错具体显示:java.lang.OutOfMemory ...
- python中的__code__
简单总结几个常用的__code__的用法: (1)func.__code__.co_argcount:返回函数的参数个数,这里的参数个数不包含*args与**kwargs,具体来讲就是*args前的参 ...
- python函数-迭代器&生成器
python函数-迭代器&生成器 一.迭代器 1 可迭代协议 迭代:就是类似for循环,将某个数据集内的数据可以“一个挨着一个取出来” 可迭代协议: ① 协议内容:内部实现__iter__方法 ...
- CVE-2010-0249(极光)分析报告
2019/9/10 报告doc在文件里面 1. 发现可疑流量 A.分析流量,导出字节流 B.得到网页代码,发现需要执行的代码需要解密(加密的字符串部分太长了,就省略了): C. ...
- 转载:Nginx做反向代理和负载均衡时“X-Forwarded-For”信息头的处理
转载自:https://blog.51cto.com/wjw7702/1150225 一.概述 如今利用nginx做反向代理和负载均衡的实例已经很多了,针对不同的应用场合,还有很多需要注意的地方,本文 ...
- Ubuntu18安装LAMP环境详细步骤
Ubuntu18安装Lamp环境 1.su root 切换root账号(root账户权限高不用总输入sudo) 更新源 阿里源网址:https://opsx.alibaba.com/mirror 更 ...
- Android之Intent相关知识
什么是Intent?Intent的作用? Intent是一个消息传递对象,我们可以通过它来启动其他组件或者在组件之间传递数据. 通过Intent启动其他组件 Intent可以用来启动Activity, ...
- Linux下C程序的内存映像
2.Linux下C程序的内存映像 2.1. 代码段.只读数据段(1)对应着程序中的代码(函数),代码段在Linux中又叫文本段(.text)(2)只读数据段就是在程序运行期间只能读不能写的数据,con ...