首页 > 解决方案 > Django Query如何对返回的对象求和

问题描述

我有一个模型:

class TimeStamp(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    t_in = models.DateTimeField(_("In"), auto_now=False, auto_now_add=False)
    t_out = models.DateTimeField(
        _("Out"), auto_now=False, auto_now_add=False, blank=True, null=True)


    class Meta:
        verbose_name = _("TimeStamp")
        verbose_name_plural = _("TimeStamps")

    def __str__(self):
        return str(f'{self.t_in.date()} {self.user.get_full_name()}')

    def get_absolute_url(self):
        return reverse("TimeStamp_detail", kwargs={"pk": self.pk})

    def get_total_hrs(self):
        if self.t_out:
            t_hrs = abs(self.t_out-self.t_in).total_seconds()/3600
        else:
            t_hrs = '0'
        return str(t_hrs)

然后在我的views.py

def timeclock_view(request):
    week_start = timezone.now().date()
    week_start -= timedelta(days=(week_start.weekday()+1) % 7)
    week_end = week_start + timedelta(days=7)

    obj = request.user.timestamp_set.filter(
        t_in__gte=week_start, t_in__lt=week_end)



    obj.aggregate(total_hrs=Sum('get_total_hrs'))

    if obj:
        last = obj.last()
        context = {'obj': obj, 'last': last,
            'week_start': week_start, 'week_end': week_end, 'week_total': total_hrs, }
    else:
        context = {}
    return render(request, 'timeclock/timeclock_view.html', context)

我如何写这个来获得查询集的总和? obj.aggregate(total_hrs=Sum('get_total_hrs))给我一个错误:

django.core.exceptions.FieldError:无法将关键字“get_total_hrs”解析为字段。选项有:description、id、note、note_set、pw、t_in、t_out、user、user_id

标签: django

解决方案


聚合在数据库上完成。这意味着您只能使用聚合中的字段,而不能使用模型函数或属性。

我将首先使用查询集实现逻辑,然后get_total_hrs使用annotate()此查询集对计算字段进行聚合。

from django.db.models.functions import Abs
from django.db.models import F, ExpressionWrapper, DurationField, Sum

queryset.annotate(
    total_hrs=ExpressionWrapper(
        Abs(F("t_out") - F("t_in")), 
        output_field=DurationField()
    ),
).aggregate(overall_hrs=Sum("total_hrs"))

推荐阅读