django queryset相加和筛选教程


Posted in Python onMay 18, 2020

1、集合相加

a = {1,2,3}
b = {3,4,5}
print(type(a))
print(a|b)

2、queryset 符合条件的筛序

projects = Project_models.objects.filter(user=request.user).order_by('id')
projects = projects.filter(bad_numbers__gt=0).order_by('bad_numbers')

补充知识:django中聚合aggregate和annotate GROUP BY的使用方法

接触django已经很长时间了,但是使用QuerySet查询集的方式一直比较低端,只会使用filter/Q函数/exclude等方式来查询,数据量比较小的时候还可以,但是如果数据量很大,而且查询比较复杂,那么如果还是使用多个filter进行查询效率就会很低。就趁着清明放假的时间,跑来公司干点私活。输出成这篇文档,一是加深印象,提高熟练度;二是分享出来,造福大家~

提高查询数据库效率的方案有两种:

第一种,是使用原生的SQL语句来进行查询,这样的优点在于能够完全按照开发者的意图来执行,效率会很高,但是缺点也很明显:

1.开发者需要非常熟悉SQL语句,加大开发者的工作量,同时,夹杂着SQL的项目也不利于以后程序的维护,增大程序的耦合度。

2.若查询条件是动态变化的,则会使开发变得更加困难。

django为了解决这一难题,提供了aggregate(聚合函数)和annotate(在aggregate的基础上进行GROUP BY操作)。

下面,就来介绍第二种方法。

一. aggregate的使用方法

今天在同事的指点下,仔细看了django中annotate的使用方法,会根据查询条件来动态生成SQL语句,提高组合查询的效率。

理解aggregate的关键在于理解SQL中的聚合函数:以下摘自百度百科:SQL基本函数,聚合函数对一组值执行计算,并返回单个值。除了 COUNT 以外,聚合函数都会忽略空值。 常见的聚合函数有AVG / COUNT / MAX / MIN /SUM 等。

aggregate就是在django中实现聚合函数的。先来看aggregate的使用场景:在项目中有时候你想要从数据库中取出一个汇总的集合。我们使用django官方的例子:

from django.db import models

class Author(models.Model):
  name = models.CharField(max_length=100)
  age = models.IntegerField()

class Publisher(models.Model):
  name = models.CharField(max_length=300)
  num_awards = models.IntegerField()

class Book(models.Model):
  name = models.CharField(max_length=300)
  pages = models.IntegerField()
  price = models.DecimalField(max_digits=10, decimal_places=2)
  rating = models.FloatField()
  authors = models.ManyToManyField(Author)
  publisher = models.ForeignKey(Publisher)
  pubdate = models.DateField()

class Store(models.Model):
  name = models.CharField(max_length=300)
  books = models.ManyToManyField(Book)
  registered_users = models.PositiveIntegerField()

如果我们使用aggregate来进行计数:

>>> from django.db.models import Count
>>> pubs = Publisher.objects.aggregate(num_books=Count('book'))
>>> pubs
{'num_books': 27}

而且aggregate不单单可以求和,还可以求平均Avg,最大最小等等。

>>> from django.db.models import Avg
>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}



# Cost per page 输出的名字同样可以指定,比如price_per_page
>>> from django.db.models import F, FloatField, Sum
>>> Book.objects.all().aggregate(
... price_per_page=Sum(F('price')/F('pages'), output_field=FloatField()))
{'price_per_page': 0.4470664529184653}

通过上面的介绍,我们可以知道,aggregate的逻辑比较简单,应用场景比较窄,如果你想要对数据进行分组(GROUP BY)后再聚合的操作,则需要使用annotate来实现。

二. annotate的使用方法

首先,假设有这么一个models:

# python:2.7.9
# django:1.7.8

class MessageTab(models.Model):
  msg_sn = models.CharField(max_lenth=20, verbose_name=u'编号')
  msg_name = models.CharField(max_length=50, verbose_name=u'消息名称')
  message_time = models.DateTimeField(verbose_name=u'消息出现时间')
  msg_status = models.CharField(max_length=50, default='未处理', verbose_name=u'消息状态')
  class Meta:
    db_table = 'message_tab'

如果在开发过程中,有这么一个需求:查询各个消息状态的数量。那么我们经常会使用filter(…).count(…)来进行查询。现在我们可以使用:

msgS = MessageTab.objects.values_list('msg_status').annotate(Count('id'))

其中,id为数据库自动生成的自增字段。values_list的用法自行Google,或者print出来看一看。

此时,数据库实际执行的代码,可以通过:

print msgS.query

打印出来。可以看到:

SELECT `message_tab`.`msg_status`, COUNT(`message_tab`.`id`) AS `id__count` FROM `message_tab` GROUP BY `message_tab`.`msg_status` ORDER BY NULL

很直观明了。通过msg_status来进行group by。如果想自定义id__count,比如指定为msg_num,则可以使用:annotate(msg_num=Count(‘id'))

当存在多个查询条件时,比如查询最近7天内,message_name属于某个分组内的消息,则可以使用Q函数:

date_end = now().date() + timedelta(days=1)
date_start = date_end - timedelta(days=7)
messageTimeRange = (date_start, date_end)
GroupList = getGroupIdLis(request.user) # 返回当前用户能查询的group的一个列表。。仅做参考用
qQueryList = [Q(message_time__range=messageTimeRange), Q(message_name__in=GroupList)] # 可以有多个Q函数查询条件

msgS = MessageTab.objects.filter(reduce(operator.and_, qQueryList)).values_list('msg_status').annotate(msg_num=Count('id'))

再次调用print msgS.query可看到SQL语句:

SELECT `message_tab`.`msg_status`, COUNT(`message_tab`.`id`) AS `msg_num` FROM `message_tab` WHERE (`message_tab`.`message_time` BETWEEN 2017-03-27 00:00:00 AND 2017-04-03 00:00:00 AND `message_tab`.`message_name` IN (1785785, 78757, 285889, 2727333, 7272957, 786767)) GROUP BY
 `message_tab`.`msg_status` ORDER BY NULL

是不是很完美!!

以上这篇django queryset相加和筛选教程就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Mac下Supervisor进程监控管理工具的安装与配置
Dec 16 Python
python监控linux内存并写入mongodb(推荐)
Sep 11 Python
Python入门之三角函数tan()函数实例详解
Nov 08 Python
详解python多线程、锁、event事件机制的简单使用
Apr 27 Python
我用Python抓取了7000 多本电子书案例详解
Mar 25 Python
Python第三方库face_recognition在windows上的安装过程
May 03 Python
python3中类的继承以及self和super的区别详解
Jun 26 Python
python写入文件自动换行问题的方法
Jul 05 Python
将pytorch转成longtensor的简单方法
Feb 18 Python
python GUI库图形界面开发之PyQt5 UI主线程与耗时线程分离详细方法实例
Feb 26 Python
python七种方法判断字符串是否包含子串
Aug 18 Python
神经网络训练采用gpu设置的方式
Mar 03 Python
python中JWT用户认证的实现
May 18 #Python
python 实现读取csv数据,分类求和 再写进 csv
May 18 #Python
python 实现分组求和与分组累加求和代码
May 18 #Python
Django ORM实现按天获取数据去重求和例子
May 18 #Python
如何实现更换Jupyter Notebook内核Python版本
May 18 #Python
python mysql自增字段AUTO_INCREMENT值的修改方式
May 18 #Python
Pycharm安装并配置jupyter notebook的实现
May 18 #Python
You might like
PHP生成网站桌面快捷方式代码分享
2014/10/11 PHP
laravel学习教程之存取器
2016/07/30 PHP
PHP编程获取图片的主色调的方法【基于Imagick扩展】
2017/08/02 PHP
PHP的mysqli_stmt_init()函数讲解
2019/01/24 PHP
微信公众平台开发教程②微信端分享功能图文详解
2019/04/10 PHP
js apply/call/caller/callee/bind使用方法与区别分析
2009/10/28 Javascript
JS 显示当前日期与时间的代码
2010/03/24 Javascript
js弹出层(jQuery插件形式附带reLoad功能)
2013/04/12 Javascript
在表单提交前进行验证的几种方式整理
2013/07/31 Javascript
js调用css属性写法
2013/09/21 Javascript
百度判断手机终端并自动跳转js代码及使用实例
2014/06/11 Javascript
javascript控制层显示或隐藏的方法
2015/07/22 Javascript
使用RequireJS库加载JavaScript模块的实例教程
2016/06/06 Javascript
微信小程序 教程之条件渲染
2016/10/18 Javascript
纯JS代码实现隔行变色鼠标移入高亮
2016/11/23 Javascript
微信小程序Server端环境配置详解(SSL, Nginx HTTPS,TLS 1.2 升级)
2017/01/12 Javascript
微信小程序开发之实现自定义Toast弹框
2017/06/08 Javascript
nodejs 如何手动实现服务器
2018/08/20 NodeJs
jQuery选择器之层次选择器用法实例分析
2019/02/19 jQuery
微信小程序实现下拉刷新动画
2019/06/21 Javascript
Vue退出登录时清空缓存的实现
2019/11/12 Javascript
解决Layui数据表格显示无数据提示的问题
2019/11/14 Javascript
Python多维/嵌套字典数据无限遍历的实现
2016/11/04 Python
Python实现MySQL操作的方法小结【安装,连接,增删改查等】
2017/07/12 Python
python中requests爬去网页内容出现乱码问题解决方法介绍
2017/10/25 Python
Python 2.7中文显示与处理方法
2018/07/16 Python
使用python itchat包爬取微信好友头像形成矩形头像集的方法
2019/02/21 Python
html5 canvas手势解锁源码分享
2020/01/07 HTML / CSS
基于html5 canvas做批改作业的小插件
2020/05/20 HTML / CSS
e路東瀛(JAPANiCAN)香港:日本旅游、日本酒店和温泉旅馆预订
2018/11/21 全球购物
大学生学习党课思想汇报
2014/01/03 职场文书
食品安全宣传标语
2014/06/07 职场文书
2015年端午节活动策划书
2015/05/05 职场文书
Java数据开发辅助工具Docker与普通程序使用方法
2021/09/15 Java/Android
python利用while求100内的整数和方式
2021/11/07 Python
Python可视化学习之seaborn调色盘
2022/02/24 Python