【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)


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, on_delete=models.CASCADE)
    pubdate = models.DateField()


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

正向查询

如果需要聚合查询某个模型相关联的其他模型的字段,我们要使用__(双下划线)
找出每家商店提供的书籍价格范围:

>>> from django.db.models import Max, Min
>>> Store.objects.annotate(min_price=Min("books__price"), max_price=Max("books__price"))
<QuerySet [<Store: Store object (1)>, <Store: Store object (2)>, <Store: Store object (3)>, <Store: Store object (4)>]>

这个规则也适用于aggregate(),找出所有商店在售书籍中的最低价格和最高价格:

>>> Store.objects.aggregate(min_price=Min("books__price"), max_price=Max("books__price"))
{'min_price': Decimal('5.00'), 'max_price': Decimal('30.00')}

还可以进行链式连接,找出在售书籍中最年轻作者的年龄:

>>> Store.objects.aggregate(youngest_age=Min("books__authors__age"))
{'youngest_age': 10}

反向查询

查询所有出版社,计算各自的书籍库存数量:

>>> from django.db.models import Avg, Count, Min, Sum
>>> Publisher.objects.annotate(Count("book"))
<QuerySet [<Publisher: Publisher object (1)>, <Publisher: Publisher object (2)>, <Publisher: Publisher object (3)>, <Publisher: Publisher object (4)>]>
>>> publishers = Publisher.objects.annotate(Count("book"))
>>> publishers[0].book__count
1

可以观察到查询结果里的每一个 Publisher 会有多余的属性—— book__count

要找到所有出版商管理的书籍中最老的一本书的出版日期:

>>> Publisher.objects.aggregate(oldest_pubdate=Min("book__pubdate"))
{'oldest_pubdate': datetime.date(2024, 3, 1)}

查询所有作者,并得到他所著书籍的总页数:

>>> Author.objects.annotate(total_pages=Sum("book__pages"))
<QuerySet [<Author: Author object (1)>, <Author: Author object (2)>, <Author: Author object (3)>, <Author: Author object (4)>]>

要找到所有作者所著书籍的平均评分:

>>> Author.objects.aggregate(average_rating=Avg("book__rating"))
{'average_rating': 9.0}
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一个甜甜的大橙子

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

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

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

打赏作者

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

抵扣说明:

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

余额充值