Django框架之模型层之聚合查询(aggregate)、分组查询(annotate)、F查询、Q查询、Meta元信息、原生SQL、综合练习、Django admin 的使用、补充知识点

十六.聚合查询 aggregate( *args,**kwargs)

1.五种聚合函数

  • Avg (Average) : 平均值
  • Max (Maximum) : 最大值
  • Min (Minimum) : 最小值
  • Sum (Summary) : 求和
  • Count : 个数

2.aggregate( )

  • aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典
  • 键的名称是聚合值的标识符,值是计算出来的聚合值
  • 键的名称是按照字段和聚合函数的名称自动生成出来的
  • 如果你想要为聚合值指定一个名称,可以向聚合子句提供它
from django.db.models import Avg,Max,Min,Sum,Count  # 导入聚合函数

res = models.Book.objects.aggregate(Avg('price')) 
print(res)  # {'price__avg': Decimal('34.204000')}

res = models.Book.objects.aggregate(avg_price=Avg('price'))  # 指定名称
print(res)  # {'avg_price': Decimal('34.204000')}

3.示例

  • 求所有数据价钱最高的, 最低的, 总和, 平均价钱
from django.db.models import Max,Min,Sum,Avg
res = models.Book.objects.aggregate(Max('price'),Min('price'),Sum('price'),Avg('price'))
print(res)  # {'price__max': Decimal('88.88'), 'price__min': Decimal('6.66'), 'price__sum': Decimal('171.02'), 'price__avg': Decimal('34.204000')}

ps : 聚合查询一般配合分组查询一起使用

十七.分组查询 annotate

以字段为依据将相同的分为一类, annotate( ) 内写聚合函数

1.分组依据

  • values( ) 在 annotate( ) 之前则表示 group by 字段
# 默认分组依据
    如果 annotate() 直接跟在 objects 后面,则表示直接以当前的基表为分组依据
    例 : 按书来分组 : odels.Book.objects.annotate(sum_price=Sum)
# 指定分组依据
    如果 annotate() 跟在 values() 后面,则表示按照values中指定的字段来进行分组
    例 : 按照书中的price进行分组 : models.Book.objects.values('price').annotate()
  • values( ) 在 annotate( ) 之后则表示取字段
  • filter( ) 在 annotate( ) 之前则表示 where 条件
  • filter( ) 在 annotate( ) 之后则表示 having 条件

2.示例:

  # from django.db.models import Max,Min,Sum,Avg

# 查询出版社id大于1的出版社id,以及出书平均价格
res = models.Book.objects.values('publish_id').filter(publish_id__gt=1).annotate(avg_price=Avg('price')).values('publish_id','avg_price')
print(res)  # <QuerySet [{'publish_id': 2, 'avg_price': Decimal('31.635000')}, {'publish_id': 3, 'avg_price': Decimal('9.435000')}]>

# 查询出版社id大于1的出版社id,以及出书平均价格大于25的
res = models.Book.objects.values('publish_id').filter(publish_id__gt=1).annotate(avg_price=Avg('price')).filter(avg_price__gt=25).values('publish_id','avg_price')
print(res)  # <QuerySet [{'publish_id': 2, 'avg_price': Decimal('31.635000')}]>

# 查询每一个出版社出版的名称和书籍个数(连表)(连表最好以group by的表作为基表)
res = models.Publish.objects.annotate(count_book=Count('book')).values('name','count_book')
print(res)  # <QuerySet [{'name': '沙河尚出版社', 'count_book': 1}, {'name': '北京出版社', 'count_book': 2}, {'name': '狗不理出版社', 'count_book': 2}]>

# 上面以Book作为基表
res = models.Book.objects.values('publish_id').annotate(book_count=Count('nid')).values('publish__name','book_count')
print(res)  # <QuerySet [{'publish__name': '沙河尚出版社', 'book_count': 1}, {'publish__name': '北京出版社', 'book_count': 2}, {'publish__name': '狗不理出版社', 'book_count': 2}]>

# 查询每个作者的名字,以及出版过书籍的最高价格(建议使用分组的表作为基表)
# 多对多如果不以分组的表作为基表, 可能会出现数据问题
res = models.Author.objects.annotate(max_price=Max('book__price')).values('name','max_price')
print(res)  # <QuerySet [{'name': 'shawn', 'max_price': Decimal('88.88')}, {'name': 'chris', 'max_price': Decimal('88.88')}, {'name': '小rub', 'max_price': Decimal('55.50')}, {'name': 'summer', 'max_price': Decimal('12.21')}]>
res = models.Book.objects.values('authors__nid').annotate(max_price=Max('price')).values('authors__name','max_price')
print(res)  # <QuerySet [{'authors__name': 'shawn', 'max_price': Decimal('88.88')}, {'authors__name': 'chris', 'max_price': Decimal('88.88')}, {'authors__name': '小rub', 'max_price': Decimal('55.50')}, {'authors__name': 'summer', 'max_price': Decimal('12.21')}]>

# 查询每一个书籍的名称, 以及对应的作者个数
res = models.Book.objects.annotate(auth_count=Count('authors__nid')).values('title','auth_count')
print(res)  # <QuerySet [{'title': '北京爱情故事', 'auth_count': 2}, {'title': '水浒传', 'auth_count': 2}, {'title': '三国演义', 'auth_count': 1}, {'title': '红楼梦', 'auth_count': 3}, {'title': '包子秘籍', 'auth_count': 2}]>

# 统计价格25元, 作者个数大于1的图书
res = models.Book.objects.filter(price__gt=25).annotate(auth_count=Count('authors__nid')).values('title','auth_count','price')
print(res)  # <QuerySet [{'title': '北京爱情故事', 'price': Decimal('88.88'), 'auth_count': 2}, {'title': '红楼梦', 'price': Decimal('55.50'), 'auth_count': 3}]>

十八. F 查询

1.F 查询介绍

  • 我们之前的例子中对一些字段的过滤和操作都是与一个常量进行比较大小, 如果我们想让字段与字段的值进行比较就无法简单实现, 于是就可以使用 F 查询了
  • 作用 : 取出某个字段对应的值

2.使用示例:

from django.db.models import F,Q  # 先导入

# 查询评论数大于阅读数的书籍
res = models.Book.objects.filter(commit_num__gt=f('read_num'))

# 将所有图书价格+5块
res = models.Book.objects.update(price=F('price')+5)
print(res)  # 5 (影响条数)

十九. Q 查询

1.Q查询介绍

  • filter 的字段筛选条件如果指定多个, 默认是and连接多个条件, 如果想要使用or或者not,则需要Q查询
  • 作用 : 构造 或 or与 &非 ~ 条件

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Django 中,聚合查询是指对模型数据进行统计、分组、排序等操作的查询。而 annotate() 是聚合查询中的一个常用方法,它可以在查询结果中添加一个聚合函数的值,并将该值作为一个新的属性添加到查询结果的每个对象中。 annotate() 方法的参数可以是一个聚合函数,也可以是一个表达式。聚合函数包括:Count、Avg、Sum、Max、Min 等,而表达式则是由模型中的字段和操作符组成的一个字符串。 以下是一些例子: ```python from django.db.models import Count from .models import Book, Author # 统计每个作者的书籍数量 authors = Author.objects.annotate(num_books=Count('book')) # 统计每个作者的平均书籍价格 authors = Author.objects.annotate(avg_price=Avg('book__price')) # 统计每个作者的最高书籍价格 authors = Author.objects.annotate(max_price=Max('book__price')) # 统计每个作者的书籍总价值 authors = Author.objects.annotate(total_price=Sum('book__price')) # 统计每个作者的书籍数量,并将结果按照数量从多到少排序 authors = Author.objects.annotate(num_books=Count('book')).order_by('-num_books') ``` 在上面的例子中,annotate() 方法的参数都是一个字符串,它们表示不同的聚合函数或表达式。其中,`'book'` 表示一个外键,它指向 Book 模型;`'book__price'` 表示一个跨表查询,它找到与 Book 关联的 Price 字段。 所以在使用 annotate() 的时候,需要根据具体的需求来设置参数,将其设置为合适的聚合函数或表达式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

给你骨质唱疏松

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值