2017-09-04 14 views
0

F()式でフィルターを使用すると、Djangoは値をグループ化できないようです。たとえば:F()式フィルター後のDjango .values()式

(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')意志グループの場所ごとの結果。しかし、私はそれを使用すると、すべての場所は1の運動選手数で複数の時間が与えられます。

+0

"最高の走りを得た場所ごとにどのようにランナーの数"を得ることができますか? (1つだけが場所のためのbest_runtimeを持っています) –

+0

はい、しかし、特定の場所では、複数のランナーが最高の走りを持つことができます。 – user2621686

+0

あなたがすること2つの場所の時間が1つのアスリートで同じになる場合?彼は両方の場所で彼を数えるべきですか?私はそう考えています。 –

答えて

0

まず、r.annotate(best_run_time = Min('trainingsession__run__run_time'))はあなたが期待していないすべてのRunオブジェクトに異なる時刻を注釈します。クエリーセットにすべてを含めるとしますが、アノテーションはオブジェクトごとに別々に行います。したがって、Runオブジェクトのオブジェクトが​​で10単位の場合、10も注釈付きです。何が本当に必要なのは、あなたがこのように使用することができaggregate()です:

><> best = Run.objects.all().aggregate(Min('run_time')) 
><> best 
>>> {'run_time__min': 10} 

あなたのクエリは次のように仕事ができる:F、注釈およびフィルタリングを使用した場合

Djangoのクエリセットのいくつかの問題がありますが、あなたが使っているDjangoのバージョンを知らなくても、正しい方向に向けるのはちょっと難しいです。