行业知识
【Django】聚合查询——连接和聚合
2026-11-11 06:55:43
来源:互联网转载
还���以下面的模型为例进行讨论,给出示例代码和示例结果
()from django.db import modelsclass 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")) 这个规则也适用于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"))>>> publishers = Publisher.objects.annotate(Count("book"))>>> publishers[0].book__count1 可以观察到查询结果里的每一个 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")) 要找到所有作者所著书籍的平均评分:
>>> Author.objects.aggregate(average_rating=Avg("book__rating")){'average_rating': 9.0}