[英]Django .aggregate() on .annotate()
是否可以聚合查詢集的注釋?
楷模:
class Article(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
class State(models.Model):
article = Models.ForeignKey(Article)
date = DateField()
views = IntegerField()
downloads = IntegerField()
我正在嘗試執行以下操作:
articles = metrics_models.Article.objects.filter(
state__date__month=month,
state__date__year=year
).annotate(
views=Min('state__views'),
downloads=Min('state__downloads')
).aggregate(
views=Sum('views'),
downloads=Sum('downloads')
)
錯誤:
Exception Type: DatabaseError
Exception Value:
column "downloads" does not exist
LINE 1: SELECT SUM(downloads), SUM(views) FROM (SELECT "metrics_arti...
運行此程序時,我收到 DatabaseError,因為 django 嘗試對“視圖”和“下載”數據庫列進行聚合,而不是對注釋進行聚合。
有沒有其他方法可以在 QuerySet 注釋上進行這種聚合?
我認為medmunds是對的,你不能重復使用相同的名稱來注釋和聚合別名。 我想你想做什么:
articles = metrics_models.Article.objects.filter(
state__date__month=month,
state__date__year=year
).annotate(
min_views=Min('state__views'),
min_downloads=Min('state__downloads')
).aggregate(
sum_min_views=Sum('min_views'),
sum_min_downloads=Sum('min_downloads')
)
根據您的原始查詢,我認為這會起作用。
from django.db.models import ExpressionWrapper, Min, OuterRef
articles = (
Article.objects.filter(state__date__month=month, state__date__year=year)
.annotate(
views=ExpressionWrapper(
Min(
State.objects.filter(article_id=OuterRef("id")).values_list(
"views", flat=True
)
),
output_field=models.IntegerField(),
),
downloads=ExpressionWrapper(
Min(
State.objects.filter(article_id=OuterRef("id")).values_list(
"downloads", flat=True
)
),
output_field=models.IntegerField(),
),
)
.aggregate(views=Sum("views"), downloads=Sum("downloads"))
)
當您對 annotate() 方法和 aggregate() 方法使用相同的字段名稱時,您將在查詢集中的每個 object 上創建一個具有該名稱的新字段,然后嘗試獲取該字段的總和。
但是,由 annotate() 方法創建的新字段與傳遞給 aggregate() 方法的字段不同。
annotate()方法在queryset中的每一個object上創建一個新字段,包含計算的結果,這個字段不存儲在數據庫中,它只存在於memory中的queryset中。
另一方面,傳遞給 aggregate() 方法的字段是對存儲在數據庫/查詢集中的字段的引用,它用於獲取存儲在數據庫中的值的總和。
因此,當您對 annotate() 和 aggregate() 方法使用相同的字段名稱時,您試圖對僅存在於 memory 中的字段的值求和(您在聚合方法上聲明的那個會覆蓋來自 annotate 的那個) ,不在數據庫/查詢集中。 這就是您沒有獲得預期結果的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.