django queryset中的跨实例计算

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 =

不确定(a)是否可行,以及(b)我是否正确制定了任务。也许正确的方法是重构数据库设计,但我希望大家能就此发表意见

我在django应用程序中有一个模型,我跟踪用户进入和退出某个页面的时间(通过提交表单或关闭broswer窗口)。我使用django通道进行跟踪,但在本例中这并不重要

模型如下所示:

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)或二次时间内运行,并且需要在
时间戳上设置一个索引(以便快速处理)。您需要排除那些
退出为无的时间