Django 系列博客(十二)

前言

本篇博客继续介绍 Django 中的查询,分别为聚合查询和分组查询,以及 F 和 Q 查询。

聚合查询

语法:aggregate(*args, **kwargs)

# 计算所有图书的平均价格
from django.db.models import Avg
Book.objects.all().aggregate(Avg('price'))

aggregate()是 QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值得标识符,值是计算出来的聚合值。建的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定个名称,可以向聚合子句提供它。

Book.objects.aggregate(average_price=Avg('price'))

如果你希望生成不止一个聚合值,你可以向 aggregate()子句中添加另一个参数。所以如果想知道所有图书价格的最大值和最小值,可以这样查询:

from django.db.models import Avg, Max, Min
Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))

具体例子:

# 查询所有书籍的平均价格
from django.db.models import Avg,Count,Max,Min
ret=Book.objects.all().aggregate(Avg('price'))
# {'price__avg': 202.896}
# 可以改名字
ret=Book.objects.all().aggregate(avg_price=Avg('price'))
# 统计平均价格和最大价格
ret=Book.objects.all().aggregate(avg_price=Avg('price'),max_price=Max('price'))
# 统计最小价格
ret = Book.objects.all().aggregate(avg_price=Avg('price'), min_price=Min('price'))
# 统计个数和平均价格
ret = Book.objects.all().aggregate(avg_price=Avg('price'), max_price=Max('price'),count=Count('price'))
ret = Book.objects.all().aggregate(avg_price=Avg('price'), max_price=Max('price'),count=Count('nid'))
print(ret)

分组查询

总结:

group by 那个表就以那个表作为基表
values 在前:表示 group by
values 在后:表示取值
filter 在前:表示 where 条件
filter 在后:表示 having

分组查询案例

# 查询所有作者写的书的总价格大于26的
# filter()在annotate后面,表示对分组后的结果进行筛选,相当于having
# annotate前的values()表示按该字段分组,相当于group by,可以省略,默认会按Author的id分组
# 后面的values()表示取值
ret=Author.objects.all().values('pk').annotate(s=Sum('book__price')).filter(s__gt=26).values('name','s') 等价于 ret=Author.objects.all().annotate(s=Sum('book__price')).filter(s__gt=26).values('name','s')
# 查询各个作者出的书的总价格
# s相当于给求和结果取名字,在vlaues取值中,可以引用
ret = Author.objects.all().annotate(s=Sum('price')).values('name','s')
print(ret)
# 统计不止一个作者的图书
ret=Book.objects.all().values('pk').annotate(c=Count('authors')).filter(c__gt=1).values('name','c')
print(ret) 等价于 ret = Book.objects.annotate(author_num=Count("authors")).filter(author_num__gt=1).values('name','author_num')
print(ret)

F 查询

什么是 F 查询

如果要对两个字段的值作比较,就不能直接比较,必须借助 F()的实例,可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。

语法

from django.db.models import F
fliter(commit_num_gt=F('read_num'))

F 查询的使用

# 查询评论数大于阅读数的书
book = models.Book.objects.filter(commit_num__gt=F('read_num')).values('name') # 把所有书的评论数加1
models.Book.objects.all().update(commit_num=F('commit_num')+1)

Q 查询

什么是 Q 查询

对两个字段的值进行或、与、非运算,不能直接运算,需要用 Q()的实例。

语法

# 且  ----->  &
# 或 -----> |
# 非 -----> ~
from django.db.models import Q
fliter(Q(name='tom')|Q(name='tony'))

Q 查询的使用

# 查询不是tom写的书的名字
ret = models.Book.objects.filter(~Q(authors__name='tom')).values('name') # 查询作者名字是tom或者名字是tony的书
ret = models.Book.objects.filter(Q(authors__name='tom')|Q(authors__name='tony')).values('name')

补充:

在实际开发中,外键通常不用:

  • 约束性太强

  • 查询效率低

  • 可以通过db_constraint=False来取消外键约束,在 orm 创建表的时候,外键的约束不会存在,但是这样会产生脏数据。

  • 建外键约束,包括 unique 都是为了不产生脏数据。

Django 系列博客(十二)的更多相关文章

  1. Django 系列博客(二)

    Django 系列博客(二) 前言 今天博客的内容为使用 Django 完成第一个 Django 页面,并进行一些简单页面的搭建和转跳. 命令行搭建 Django 项目 创建纯净虚拟环境 在上一篇博客 ...

  2. Django 系列博客(十六)

    Django 系列博客(十六) 前言 本篇博客介绍 Django 的 forms 组件. 基本属性介绍 创建 forms 类时,主要涉及到字段和插件,字段用于对用户请求数据的验证,插件用于自动生成 h ...

  3. Django 系列博客(十)

    Django 系列博客(十) 前言 本篇博客介绍在 Django 中如何对数据库进行增删查改,主要为对单表进行操作. ORM简介 查询数据层次图解:如果操作 mysql,ORM 是在 pymysql ...

  4. Django 系列博客(十四)

    Django 系列博客(十四) 前言 本篇博客介绍在 html 中使用 ajax 与后台进行数据交互. 什么是 ajax ajax(Asynchronous Javascript And XML)翻译 ...

  5. Django 系列博客(十三)

    Django 系列博客(十三) 前言 本篇博客介绍 Django 中的常用字段和参数. ORM 字段 AutoField int 自增列,必须填入参数 primary_key=True.当 model ...

  6. Django 系列博客(十一)

    Django 系列博客(十一) 前言 本篇博客介绍使用 ORM 来进行多表的操作,当然重点在查询方面. 创建表 实例: 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日 ...

  7. Django 系列博客(六)

    Django 系列博客(六) 前言 本篇博客介绍 Django 中的路由控制部分,一个网络请求首先到达的就是路由这部分,经过路由与视图层的映射关系再执行相应的代码逻辑并将结果返回给客户端. Djang ...

  8. Django 系列博客(九)

    Django 系列博客(九) 前言 本篇博客介绍 Django 模板的导入与继承以及导入导入静态文件的几种方式. 模板导入 模板导入 语法:``{% include '模板名称' %} 如下: < ...

  9. Django 系列博客(八)

    Django 系列博客(八) 前言 本篇博客介绍 Django 中的模板层,模板都是Django 使用相关函数渲染后传输给前端在显式的,为了想要渲染出我们想要的数据,需要学习模板语法,相关过滤器.标签 ...

随机推荐

  1. JPG、PNG、GIF、SVG 等格式图片区别

    1.图片 2. 前言 首先,我们要清楚的是,图片从类型上分,可以分为 位图 和 矢量图. 位图:位图又叫点阵图或像素图,计算机屏幕上的图是由屏幕上的发光点(即像素)构成的,每个点用二进制数据来描述其颜 ...

  2. Springboot搭建SSM+JSP的web项目

    Springboot搭建SSM+JSP的web项目 一:创建项目结构: 项目结构分为三个部分: 1 后端项目开发文件: 包: Util         工具包 Mapper      db层 Serv ...

  3. 封装一个 员工类 使用preparedStatement 查询数据 (2) 使用 arrayList 集合

    创建 员工=类生成 有参构造 get set 方法 toString 方法 package cn.hph; public class emp1 { //创建员工类的属性 private int id; ...

  4. Bandwagon的配置记录(一) —— kexue上网

    写在前面 这是kexue上网的一种方法. 看文章前,先拉最底下,看一遍“写在最后”. 租个服务器 我租了个洛杉矶的服务器,系统是ubuntu16.04 x86_64 进入KiwiVM Control ...

  5. changXY

    changXY <!DOCTYPE html> <html> <head> <link rel="shortcut icon" href= ...

  6. 二分(HDU2289 Cup)

    贴代码: 题目意思:已知r水的下半径,R水的上半径,H为圆台高度,V为水的体积,求水的高度,如图: 水的高度一定在0-100,所以在这个区间逐步二分,对每次二分出的水的高度,计算相应的体积,看看计算出 ...

  7. 原生js实现删除class和添加class

    内容来自百度搜索 //判断样式是否存在 function hasClass(ele, cls) {     return ele.className.match(new RegExp("(\ ...

  8. JS HTML DOM代码(1)

    <!DOCTYPE html> <html> <style type="text/css"> #容器 { width: 400px; heigh ...

  9. js发送post请求,实现下载文件

    由于业务需求要下载文件的功能: <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...

  10. [Swift]LeetCode186. 翻转字符串中的单词 II $ Reverse Words in a String II

    Given an input string, reverse the string word by word. A word is defined as a sequence of non-space ...