我有两个模型,项目和会话。一个项目可以有多个会话,一个用户可以有多个项目。
class Project(models.Model):
class Meta:
ordering = [models.functions.Lower("name")]
name = models.CharField(max_length=255)
user = models.ForeignKey(User, on_delete=models.CASCADE)
class Session(models.Model):
start = models.DateTimeField()
end = models.DateTimeField()
timezone = TimeZoneField()
breaks = models.IntegerField(default=0, validators=[MinValueValidator(0)])
project = models.ForeignKey(Project, on_delete=models.CASCADE)
def duration(self):
# returns minutes in (end - start)
我希望有一种方法可以获取给定用户的所有项目,并按其所有会话中持续时间的总和进行排序。由于
session.duration()
不是数据库字段,而是从数据库字段计算得出的,因此我无法在单个数据库查询中获取此信息。我的当前解决方案是:
sessions = Session.objects.filter(project__user=self)
groups = [[a, sum([s.duration() for s in b])] for a, b in groupby(
sessions, key=lambda s: s.project
)]
groups = sorted(groups, key=lambda g: g[1], reverse=True)
return [g[0] for g in groups]
这段代码使用单个查询获取所有相关会话,但是它需要按项目分组,这样会花费很长时间 - 当有大约100个项目时,需要大约1秒钟。是否有一种更快的方法来实现这一点?最好不需要为每个项目进行数据库调用。
我正在使用Django 2.0。
total
是每个会话持续时间的总和。我需要的输出是按项目的总持续时间排序的项目列表。我感觉您已经完成了90%,只是我无法弄清如何使用上面的duration_
字段来实现这一点。 - Sam Ireland