如何计算 Django 的总工作时间?
How to calculate total working hours in Django?
我创建了以下模型:
class Timesheet(models.Model):
date = models.DateField(auto_now=False, auto_now_add=False, verbose_name="Data")
entry = models.TimeField(auto_now=False, auto_now_add=False, verbose_name="Hora Entrada")
lunch = models.TimeField(auto_now=False, auto_now_add=False, null=True, blank=True, verbose_name="Início do Almoço")
lunch_end = models.TimeField(auto_now=False, auto_now_add=False, null=True, blank=True, verbose_name="Fim do Almoço")
out = models.TimeField(auto_now=False, auto_now_add=False, verbose_name="Hora de Saída")
然后在 table 中返回,其中有一个名为“总时数”的额外字段,我需要在其中计算总工作时数。每个条目都指同一天。
而我的看法是:
def timesheet(request):
c = Timesheet.objects.all()
context = {'c': c}
return render(request, "tracker/timesheet.html", context)
我需要做的计算是:(out - entry) - (lunch_end - lunch)
.
我怎样才能做到这一点?
您可以 .annotate(…)
[Django-doc] 每个 Timesheet
对象:
from django.db.models import DurationField, ExpressionWrapper, F, IntegerField
Timesheet.objects.annotate(
total_time=ExpressionWrapper(
ExpressionWrapper(F('out') - F('entry'), output_field=IntegerField()) -
ExpressionWrapper(F('lunch_end') - F('lunch'), output_field=IntegerField()),
output_field=DurationField()
)
)
这里从 this 查询集产生的每个 Timesheet
对象将有一个额外的属性 .total_time
,它将包含该人工作的持续时间(因此减去午休)。
或者您可以用 .aggregate(…)
[Django-doc]:
对所有记录求和
from django.db.models import DurationField, ExpressionWrapper, F, IntegerField
Timesheet.objects.<b>aggregate(</b>
total_time=<b>Sum(</b>
ExpressionWrapper(F('out') - F('entry'), output_field=IntegerField()) -
ExpressionWrapper(F('lunch_end') - F('lunch'), output_field=IntegerField()),
output_field=DurationField()
<b>)</b>
)['total_time']
如果 lunch
和 lunch_end
可以是 None
/NULL
,你可以使用 Coalesce
[Django-doc]:
from django.db.models import DurationField, ExpressionWrapper, F, IntegerField, Value
from django.db.models.functions import Coalesce
Timesheet.objects.<b>aggregate(</b>
total_time=<b>Sum(</b>
ExpressionWrapper(F('out') - F('entry'), output_field=IntegerField()) -
Coalesce(ExpressionWrapper(F('lunch_end') - F('lunch'), output_field=IntegerField()), Value(0)),
output_field=DurationField()
<b>)</b>
)['total_time']
如果你因此有 .annotate(…)
d 所有 Timesheet
条记录,并将它们作为 c
传递,你可以使用:
{% for ci in c %}
{{ ci.data }}: {{ ci.entry }} - {{ ci.out }}; {{ <b>ci.</b>total_time }}
{% endfor %}
我创建了以下模型:
class Timesheet(models.Model):
date = models.DateField(auto_now=False, auto_now_add=False, verbose_name="Data")
entry = models.TimeField(auto_now=False, auto_now_add=False, verbose_name="Hora Entrada")
lunch = models.TimeField(auto_now=False, auto_now_add=False, null=True, blank=True, verbose_name="Início do Almoço")
lunch_end = models.TimeField(auto_now=False, auto_now_add=False, null=True, blank=True, verbose_name="Fim do Almoço")
out = models.TimeField(auto_now=False, auto_now_add=False, verbose_name="Hora de Saída")
然后在 table 中返回,其中有一个名为“总时数”的额外字段,我需要在其中计算总工作时数。每个条目都指同一天。
而我的看法是:
def timesheet(request):
c = Timesheet.objects.all()
context = {'c': c}
return render(request, "tracker/timesheet.html", context)
我需要做的计算是:(out - entry) - (lunch_end - lunch)
.
我怎样才能做到这一点?
您可以 .annotate(…)
[Django-doc] 每个 Timesheet
对象:
from django.db.models import DurationField, ExpressionWrapper, F, IntegerField
Timesheet.objects.annotate(
total_time=ExpressionWrapper(
ExpressionWrapper(F('out') - F('entry'), output_field=IntegerField()) -
ExpressionWrapper(F('lunch_end') - F('lunch'), output_field=IntegerField()),
output_field=DurationField()
)
)
这里从 this 查询集产生的每个 Timesheet
对象将有一个额外的属性 .total_time
,它将包含该人工作的持续时间(因此减去午休)。
或者您可以用 .aggregate(…)
[Django-doc]:
from django.db.models import DurationField, ExpressionWrapper, F, IntegerField
Timesheet.objects.<b>aggregate(</b>
total_time=<b>Sum(</b>
ExpressionWrapper(F('out') - F('entry'), output_field=IntegerField()) -
ExpressionWrapper(F('lunch_end') - F('lunch'), output_field=IntegerField()),
output_field=DurationField()
<b>)</b>
)['total_time']
如果 lunch
和 lunch_end
可以是 None
/NULL
,你可以使用 Coalesce
[Django-doc]:
from django.db.models import DurationField, ExpressionWrapper, F, IntegerField, Value
from django.db.models.functions import Coalesce
Timesheet.objects.<b>aggregate(</b>
total_time=<b>Sum(</b>
ExpressionWrapper(F('out') - F('entry'), output_field=IntegerField()) -
Coalesce(ExpressionWrapper(F('lunch_end') - F('lunch'), output_field=IntegerField()), Value(0)),
output_field=DurationField()
<b>)</b>
)['total_time']
如果你因此有 .annotate(…)
d 所有 Timesheet
条记录,并将它们作为 c
传递,你可以使用:
{% for ci in c %}
{{ ci.data }}: {{ ci.entry }} - {{ ci.out }}; {{ <b>ci.</b>total_time }}
{% endfor %}