2016-12-02 50 views
0

我試圖與Django的一些有效的查詢在下面的循環:Django的:準備查詢,但不執行它

for division in divisions: 
    playoffs = league.playoff_set.filter(division=division, double_elimination=True) 

我想,也許在循環之前只選擇那些與double_elimination=True過濾playoffs會提高它:

playoffs = league.playoff_set.filter(double_elimination=True) 
for division in divisions: 
    division_playoffs = playoffs.filter(division=division) 

但現在我擔心的是,這是在循環,而不是在先前檢索結果過濾擊發playoffs查詢在每次運行。

它按預期工作還是我擔心?我應該用Q來建立這些性能更好的查詢嗎?

+0

Django查詢集很懶,它們沒有執行直到你需要結果。 – Sayse

回答

4

Django querysets are lazy。這意味着,當你做

playoffs = league.playoff_set.filter(double_elimination=True) 

它,當你在循環再次過濾查詢集甚至沒有評估的查詢集未評估。

division_playoffs = playoffs.filter(division=division) 

The queryset will only be evaluated當您訪問其內容(無論是在視圖或模板)。

playoffs = league.playoff_set.filter(double_elimination=True) 
for division in divisions: 
    division_playoffs = playoffs.filter(division=division) 
    for playoff in division_playoffs: # looping through queryset causes it to be evaluated 
     print(playoff) 

因此,您的代碼的兩個版本都將工作相同。你應該選擇一個你認爲更清晰的。

+0

因此,即使我堅持原來的方法(當每個循環中的查詢是'playoffs = league.playoff_set.filter(division = division,double_elimination = True)'),它會一樣有效嗎? – dabadaba

+0

您可以使用類似Django調試工具欄的東西來查看生成的SQL查詢。正如我所說的,你的代碼的兩個版本都是一樣的。 – Alasdair

+0

您可以查看已經運行的SQL查詢,可以幫助您瞭解引擎蓋下的情況。 http://stackoverflow.com/questions/1074212/how-to-show-the-sql-django-is-running 如果有大量的分歧,但不是絕大多數季後賽,它可能是最好的只是查詢'league.playoff_set.filter(double_elimination = True)',然後將結果分組到python中。例如。 http://stackoverflow.com/questions/31071888/python-group-list-items-in-a-dict –