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 相关文章推荐
Python 执行字符串表达式函数(eval exec execfile)
Aug 11 Python
用Python实现协同过滤的教程
Apr 08 Python
python简单分割文件的方法
Jul 30 Python
基于循环神经网络(RNN)实现影评情感分类
Mar 26 Python
使用python画个小猪佩奇的示例代码
Jun 06 Python
pandas 实现字典转换成DataFrame的方法
Jul 04 Python
Python函数参数匹配模型通用规则keyword-only参数详解
Jun 10 Python
python爬虫 urllib模块发起post请求过程解析
Aug 20 Python
python集合常见运算案例解析
Oct 17 Python
在 Python 中接管键盘中断信号的实现方法
Feb 04 Python
jupyter 中文乱码设置编码格式 避免控制台输出的解决
Apr 20 Python
pycharm不以pytest方式运行,想要切换回普通模式运行的操作
Sep 01 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/03/02 PHP
让你的PHP7更快之Hugepage用法分析
2016/05/31 PHP
php生成二维码不保存服务器还有下载功能的实现代码
2018/08/09 PHP
php使用array_chunk函数将一个数组分割成多个数组
2018/12/05 PHP
Yii2.0 RESTful API 基础配置教程详解
2018/12/26 PHP
js/jquery获取浏览器窗口可视区域高度和宽度以及滚动条高度实现代码
2012/12/17 Javascript
js中的caller和callee属性介绍和例子
2014/06/07 Javascript
jQuery插件Skippr实现焦点图幻灯片特效
2015/04/12 Javascript
关于事件mouseover ,mouseout ,mouseenter,mouseleave的区别
2015/10/12 Javascript
AngularJS中update两次出现$promise属性无法识别的解决方法
2017/01/05 Javascript
解决URL地址中的中文乱码问题的办法
2017/02/10 Javascript
Vue.js 60分钟快速入门教程
2017/03/28 Javascript
JavaScript实现实时更新系统时间的实例代码
2017/04/04 Javascript
BACKBONE.JS 简单入门范例
2017/10/17 Javascript
JS实现区分中英文并统计字符个数的方法示例
2018/06/09 Javascript
vue中使用gojs/jointjs的示例代码
2018/08/24 Javascript
Vue事件修饰符native、self示例详解
2019/07/09 Javascript
[04:53]DOTA2英雄基础教程 祈求者
2014/01/03 DOTA
[02:09:59]火猫TV国士无双dota2 6.82版本详解(下)
2014/09/29 DOTA
Python实现Linux的find命令实例分享
2017/06/04 Python
Hotels.com南非:酒店预订
2017/11/02 全球购物
旅游业大学生创业计划书
2014/01/31 职场文书
《鸟的天堂》教学反思
2014/02/27 职场文书
带病坚持工作事迹
2014/05/03 职场文书
我们的节日元宵活动方案
2014/08/23 职场文书
树转促学习心得体会
2014/09/10 职场文书
2014幼儿园教师个人工作总结
2014/11/08 职场文书
长城导游词
2015/01/30 职场文书
公司财务部岗位职责
2015/04/14 职场文书
党小组推荐意见
2015/06/02 职场文书
创业计划书之面包店
2019/09/17 职场文书
Python多个MP4合成视频的实现方法
2021/07/16 Python
idea以任意顺序debug多线程程序的具体用法
2021/08/30 Java/Android
Mysql数据库表中为什么有索引却没有提高查询速度
2022/02/24 MySQL
解决Git推送错误non-fast-forward的方法
2022/06/25 Servers
Python爬取奶茶店数据分析哪家最好喝以及性价比
2022/09/23 Python