Django 注释和聚合

Django Annotate and Aggregate

我想对每个 post_user 的所有帖子的 post_value 求和,以最终在图表中使用。我正在为如何制定查询而苦恼?

到目前为止,我必须:

user_totals = User.objects.annotate(post_value_total=Sum('post'))

models.py

class User(AbstractUser):
    pass

class Post(models.Model):
    post_user = models.ForeignKey(User, on_delete=models.CASCADE)
    post_cat = models.ForeignKey(Category, on_delete=models.CASCADE)
    post_action = models.ForeignKey(Action, on_delete=models.CASCADE)
    post_quantity = models.PositiveIntegerField(blank=True, null=True)
    post_value = models.PositiveIntegerField(default='0')
    post_timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return f"{self.post_user}'s post at {self.post_timestamp}"

谢谢。

I'd like to Sum the post_value of all of the Posts for each post_user to eventually use in a chart.

由于每个Post都有一个不可为空的post_userForeignKey,这意味着每个Post属于恰好一个用户。

因此,我们可以将所有 User 中的 post_value 的数量加起来为:

Post.objects.all()<b>.count()</b>

如果您只想对一部分用户进行汇总,您可以使用:

Post.objects.<b>filter(</b>
    post_user__in=[user<sub>1</sub>, user<sub>2</sub>, user<sub>3</sub>]
<b>)</b>.count()

或者如果您有 ID:

Post.objects.<b>filter(</b>
    post_user_id__in=[user_id<sub>1</sub>, user_id<sub>2</sub>, user_id<sub>3</sub>]
<b>)</b>.count()

或者如果你想总结 post_values,你可以使用:

from django.db.models import Sum

total_post_value = Post.objects.aggregate(
    <b>total=Sum('post_value')</b>
) or 0

如果集合可以为空,则or 0是必需的,因为没有记录的总和是NULL/None,而不是0.

或者,如果您想这样做 per User,我们可以使用:

user_totals = User.objects.annotate(
    <b>post_value_total=Sum('post__post_value')</b>
)

由此产生的User对象将有一个额外的属性post_value_total,它总结了相关Post的值.如果用户没有相关的 Post,则这些可以是 None。在那种情况下,我们可以工作 Coalesce [Django-doc]:

from django.db.models import Sum, Value
from django.db.models.functions import Coalesce

user_totals = User.objects.annotate(
    <b>post_value_total=Coalesce(Sum('post__post_value'), Value(0))</b>
)