2017-07-07 90 views
3

我正在製作一個簡單的Django應用程序,用於記錄跑步運動員的表現。該應用程序的模式是這樣的:Django外鍵選擇

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) 

一個運動員有多個培訓課程,並在每個這些會議的,運動員運行多次(每次,他的時間將被記錄以秒計)。

我發現,我可以很容易地在這些模型之間進行查詢,但是,我仍然在努力解決以下問題: 我想要選擇在20秒和30秒之間運行的跑步者。當我選擇跑步是這樣的:

athletes = Athlete.filter(trainingsession__run__run_time__range=[20,30]).distinct() 

我得到一次跑35秒​​,一旦20到30秒之間跑了所有的運動員,而且運動員。你能幫我解決這個問題嗎?希望有一個Django查詢可以讓這個變得簡單!

回答

2

您可以在<20>30秒內找到另外一組運動員的查詢集,並將它們從您的athletes查詢集中排除。您可以使用Q() 執行OR查詢。

excluded_athletes = Athlete.filter(Q(trainingsession__run__run_time__gte=30)|Q(trainingsession__run__run_time__lte=20)).distinct().values_list('id',flat=True) 
athletes = Athlete.filter(trainingsession__run__run_time__range=[20,30]).distinct() 
athletes.exclude(id__in=excluded_athletes) 
0

Q對象可以幫助建立更復雜的查詢: https://docs.djangoproject.com/en/1.11/topics/db/queries/#complex-lookups-with-q-objects

也許是這樣的:

athletes = Athlete.filter(
    Q(trainingsession__run__run_time__gt=20) & 
    Q(trainingsession__run__run_time__lt=30)).distinct() 

而且使用.distinct()的時候有一些陷阱。訂單發揮作用,您可以指定要區分的字段。 參閱文檔:https://docs.djangoproject.com/en/1.11/ref/models/querysets/#django.db.models.query.QuerySet.distinct