django queryset中的跨实例计算
不确定(a)是否可行,以及(b)我是否正确制定了任务。也许正确的方法是重构数据库设计,但我希望大家能就此发表意见 我在django应用程序中有一个模型,我跟踪用户进入和退出某个页面的时间(通过提交表单或关闭broswer窗口)。我使用django通道进行跟踪,但在本例中这并不重要 模型如下所示:django queryset中的跨实例计算,django,django-models,django-queryset,Django,Django Models,Django Queryset,不确定(a)是否可行,以及(b)我是否正确制定了任务。也许正确的方法是重构数据库设计,但我希望大家能就此发表意见 我在django应用程序中有一个模型,我跟踪用户进入和退出某个页面的时间(通过提交表单或关闭broswer窗口)。我使用django通道进行跟踪,但在本例中这并不重要 模型如下所示: class TimeStamp(models.Model): class Meta: get_latest_by = 'enter_time' page_name =
class TimeStamp(models.Model):
class Meta:
get_latest_by = 'enter_time'
page_name = models.CharField(max_length=1000)
participant = models.ForeignKey(to=Participant, related_name='timestamps')
timestamp = models.DateTimeField()
enter_exit_type = models.CharField(max_length=1000, choices=ENTEREXITTYPES,)
我需要做的是计算用户在这个页面上花费的时间。因此,我需要遍历特定用户的Timestamp
的所有记录,并计算“enter”和“exit”类型记录之间的时间差
因此,db数据可能如下所示:
id timestamp enter_exit_type
1 20:12:12 enter
2 20:12:13 exit
3 20:18:12 enter
4 20:21:12 exit
5 20:41:12 enter
id time_spent_sec
1 0:01
2 3:00
那么,生成结果查询集的正确方法是什么呢
id timestamp enter_exit_type
1 20:12:12 enter
2 20:12:13 exit
3 20:18:12 enter
4 20:21:12 exit
5 20:41:12 enter
id time_spent_sec
1 0:01
2 3:00
由于没有相应的“退出”记录,最后一条“输入”记录被忽略。
结果queryset中的记录1是ids2和ids1中时间戳之间的差异。结果queryset中的记录2是IDS4和IDS3中时间戳之间的差异
我可以循环查看记录,查找最近的“退出”记录并计算它,但我在想是否有更简单的解决方案?可能:
1) 如果要在一个查询中获得所有用户的答案,请使用按用户分组的方法
2) 使用enter\u exit\u type==“enter”
过滤掉最后一个未关闭的条目
3) .annotate(时间戳_,带符号=Case(当(输入_exit_type='exit',然后=F('timestamp')*-1),默认值=F('timestamp'),)
4) Sum()由带有符号字段的时间戳_进行计算
我不确定F(“时间戳”)是否有效,您可能需要搜索将其转换为unix时间的方法。此模型结构可能不足以满足您的要求。所以我建议把你的模型改成
class TimeStamp(models.Model):
class Meta:
get_latest_by = 'enter_time'
page_name = models.CharField(max_length=1000)
participant = models.ForeignKey(Musician, related_name='timestamps')
enter = models.DateTimeField()
exit = models.DateTimeField(null=True, blank=True)
然后你会得到如下数据:
from django.db.models import F, Sum, ExpressionWrapper, DurationField
TimeStamp.objects.values(
'participant').annotate(
sum_time_diff=Sum(
ExpressionWrapper(F('exit') - F('enter'), output_field=DurationField())
)
)
从django.db.models导入F、Sum、ExpressionWrapper、DurationField
TimeStamp.objects.values(
“参与者”)。注释(
总和时间之差=总和(
ExpressionWrapper(F('exit')-F('enter'),output\u field=DurationField())
)
)
答案可能是
<QuerySet [{'participant': 1, 'sum_time_diff': datetime.timedelta(0, 7)}, {'participant': 2, 'sum_time_diff': datetime.timedelta(0, 2)}]>
什么是类型
?抱歉,它实际上被称为事件类型。是进入还是退出(取决于一个人此时是进入页面还是退出页面)这是模型中的enter\u exit\u type
?是的,完全正确。你是对的。抱歉,不明确是可能的,使用子查询,但它通常会在(n log n)或二次时间内运行,并且需要在时间戳上设置一个索引(以便快速处理)。您需要排除那些退出为无的时间