aggregate:聚合
annotate:分组
Django的aggregate和annotate方法属于高级查询方法,主要用于组合查询。
当我们需要对查询集(queryset)的某些字段,进行计算,或进行先分组,再计算或排序, 我们就需要使用aggregate和annotate方法了。
一般搭配聚合函数进行使用。
- from django.db import models
-
-
- class Tag(models.Model):
- name = models.CharField(verbose_name='标签名称', max_length=225)
-
- def __str__(self):
- return self.name
-
-
- class Article(models.Model):
- title = models.CharField(verbose_name='标题', max_length=225)
- content = models.CharField(verbose_name='内容', max_length=225)
- # 外键
- tag = models.ManyToManyField(verbose_name='标签', to='Tag', related_name='tag_article')
- price = models.DecimalField(max_digits=4, decimal_places=2)
-
- def __str__(self):
- return self.title
- from django.db.models import F, Max, Min, Avg
-
- from blog import models
-
- # 计算所有文章价格的平均值 # {'price__avg': Decimal('50.000000')}
- article_queryset = models.Article.objects.all().aggregate(Avg('price'))
-
- # 计算所有文章价格的总价钱 ,并其名称叫sum_price # {'sum_price': Decimal('250.00')}
- article_queryset = models.Article.objects.aggregate(sum_price=Sum('price'))
-
- # 文章最大价格 # {'max_price': Decimal('50.00')}
- article_queryset = models.Article.objects.aggregate(max_price=Max('price'))
-
- # # 同时获取文章价格的平均值, 价格的总价钱, 文章最大价格 # {'price_avg': Decimal('50.000000'), 'price_sum': Decimal('250.00'), 'price_max': Decimal('50.00')}
- article_queryset = models.Article.objects.aggregate(price_avg=Avg('price'), price_sum=Sum('price'),
- price_max=Max('price'))
-
- # 根据标签反查文章的最大价格 # {'max_price': Decimal('50.00')}
- article_queryset = models.Tag.objects.filter(id=1).first().tag_article.all().aggregate(max_price=Max('price'))
- print(article_queryset)
- # 基础使用(配合values使用)
- # 按标签名称分组,再统计每组文章的最大价格
- #
- article_queryset = models.Tag.objects.values('name').annotate(Max('tag_article__price'))
-
- # 按文章标题进行分组,统计每个文章下面有多少标签
- #
- # {'title': 'fas', 'tag__count': 1}, {'title': '凤梨的108种吃法', 'tag__count': 1}]>
- article_queryset = models.Article.objects.values('title').annotate(Count('tag'))
-
- # 按文章标题进行分组,统计每个文章下面有多少标签,并定义返回的数据名称
- article_queryset = models.Article.objects.values('title').annotate(tag_count=Count('tag'))
-
- # 按标签名称分组,再统计每组文章数量
- article_queryset = models.Tag.objects.values('name').annotate(Count('tag_article'))
-
- # Annotate方法与Filter方法联用
-
- # 先按标签名称分组,再统计每组文章数量, 然后筛选出文章数量大于1的数据
- #
- article_queryset = models.Tag.objects.values('name').annotate(article_count=Count('tag_article')).filter(
- article_count__gt=1)
-
- # Annotate方法与order_by
- # 先按标签名称分组,再统计每组文章数量, 然后筛选出文章数量大于1的数据,最后以id倒叙排列
- article_queryset = models.Tag.objects.values('name').annotate(article_count=Count('tag_article')).filter(
- article_count__gt=1).order_by('-id')
-
- # 分组聚合联合使用
- # 先按标签名称分组,再统计每组文章数量, 然后筛选出文章数量大于1的数据,最后以id倒叙排列,取出标签id最大值
- article_queryset = models.Tag.objects.values('name').annotate(article_count=Count('tag_article')).filter(
- article_count__gt=1).order_by('-id').aggregate(Max('id'))
(2条消息) aggregate和annotate方法使用详解与示例_weixin_33970449的博客-CSDN博客