使用带有F()表达式的过滤器后,似乎Django无法对值进行分组。例如:
(models.py)
class Athlete(models.Model):
name = models.CharField(max_length=30)
nationality = models.CharField(max_length=30)
class TrainingSession(models.Model):
training_date = models.DateTimeField()
location = models.CharField(max_length=30)
athlete = models.ForeignKey(Athlete)
class Run(models.Model):
run_time = models.IntegerField()
training = models.ForeignKey(TrainingSession)
(views.py) 我希望每个位置都有最佳跑步者的跑步者数量。
r = Run.objects.all()
# Annotate the best time from the training session and filter
r = r.annotate(best_run_time = Min('trainingsession__run__run_time'))
r = r.filter(run_time = F('best_run_time'))
# Group by location
r = r.values('location')
r = r.annotate( athlete_count = Count('trainingsession_athlete', distinct=True))
当我不使用F()
表达式时,.values('location')
会按位置对结果进行分组。但是,当我使用它时,每个位置都会被赋予一个Athle_count为1的多次。
答案 0 :(得分:0)
首先,r.annotate(best_run_time = Min('trainingsession__run__run_time'))
将为每个Run
对象注释不同的时间,这不是您所期望的。您希望在查询集中包含所有内容,但是注释会为每个对象单独进行注释,因此如果Run
对象的run_time
为10个单位,则10也会进行注释。您真正需要的是aggregate()
,您可以这样使用:
><> best = Run.objects.all().aggregate(Min('run_time'))
><> best
>>> {'run_time__min': 10}
您的查询可以这样工作:
Run.objects.filter(run_time=best['run_time__min']).values('location')
使用F
,注释和过滤时,Django查询集存在一些问题,但是如果不知道您使用的是哪个Django版本,则很难指出正确的方向。