我有一个带有两个日期时间的模型,一个用于创建日期,另一个用于完成日期。
class Task(models.Model):
...
created = models.DateTimeField(default=timezone.now)
STATUS = Choices(
('draft', 'Draft'),
('open', 'Open'),
('wip', 'In Progress'),
('completed', 'Completed'),
)
datetime_started = models.DateTimeField(blank=True, null=True)
datetime_wip = models.DateTimeField(blank=True, null=True)
datetime_completed = models.DateTimeField(blank=True, null=True)
...
我正在尝试注释一个查询集来计算完成Task
所需的平均时间。我尝试使用Django的Avg
和F
表达式,但无济于事:
today = timezone.now()
# We display the data of last 11 months + this month
tzinfo = timezone.get_current_timezone()
start_date = datetime(
today.year,
today.month,
1,
tzinfo=tzinfo) - relativedelta(months=11)
where = ("date_trunc('month', tasks_task.created AT TIME ZONE '%s')::date"
% timezone.get_current_timezone_name())
tasks_last_12 = Task.objects.filter(
created__range=(start_date, today),
)
.extra({'month': where})
.values('month')
.order_by('month')
.annotate(
cmpl_time=Avg(F('datetime_completed') - F('datetime_started')),
)
.values_list('month', 'cmpl_time')
...
TypeError: float() argument must be a string or a number, not 'datetime.timedelta'
然后,我尝试使用Sum
和Count
的组合来计算平均值,但这也不起作用:
tasks_last_12 = Task.objects.filter(
created__range=(start_date, today),
)
.extra({'month': where})
.values('month')
.order_by('month')
.annotate(
cmpl_time=Sum(
(F('datetime_completed') - F('datetime_started')) / Count('datetime_completed')
)
)
.values_list('month', 'cmpl_time'))
...
FieldError: Expression contains mixed types. You must set output_field
我怎么能解决这个问题呢?
答案 0 :(得分:1)
如果您使用的是Postgres,则可以使用django-pg-utils包。将持续时间字段转换为秒,然后取平均值
from pg_utils import Seconds
from django.db.models import Avg
Task.objects.annotate(cmpl_time=Avg(Seconds(F('datetime_completed') - F('datetime_started'))))
答案 1 :(得分:0)
迟到的回复,但是:
date1 - date2
将为您提供timedelta
个对象。求和,然后除以列表的len
。Sum(..., output_field=DateField())
Sum
之前调用Count
以计算平均值。