2016-12-02 1 views
0

ich in der folgenden Schleife einige effiziente Abfragen mit Django zu machen versuche:Django: Abfrage vorbereiten, aber nicht ausführen es

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

ich vielleicht playoffs vor der Schleife dachte Filterung nur von denen mit double_elimination=True Auswahl würde verbessern sie:

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

Aber jetzt bin ich besorgt, dass dies in der Schleife die Abfrage von playoffs in jedem Lauf feuert statt Filterung auf dem zuvor abgerufene Ergebnis.

Funktioniert es wie erwartet oder wie befürchte ich? Sollte ich stattdessen Q verwenden, um diese Abfragen mit besserer Leistung zu erstellen?

+0

Django-Abfragesätze sind faul, sie werden nicht ausgeführt, bis Sie die Ergebnisse benötigen. – Sayse

Antwort

4

Django querysets are lazy. Das bedeutet, dass die queryset nicht ausgewertet, wenn Sie tun

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

Es ist nicht einmal ausgewertet, wenn Sie die queryset wieder in der Schleife filtern.

division_playoffs = playoffs.filter(division=division) 

The queryset will only be evaluated beim Zugriff auf seine Inhalte (entweder in der Ansicht oder in der Vorlage).

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) 

Daher funktionieren beide Versionen Ihres Codes gleich. Sie sollten diejenige auswählen, die Sie für klarer halten.

+0

Also, selbst wenn ich bei der ursprünglichen Herangehensweise geblieben wäre (wenn die Abfrage "playoffs = league.playoff_set.filter (division = division, double_elimination = True)" in jeder Schleife war, wäre es genauso effizient? – dabadaba

+0

Sie können etwas wie die Django-Debug-Symbolleiste verwenden, um sich die resultierenden SQL-Abfragen anzusehen. Wie gesagt, beide Versionen Ihres Codes werden gleich funktionieren. – Alasdair

+0

Sie können SQL-Abfragen anzeigen, die ausgeführt wurden, um zu verstehen, was unter der Haube passiert. http://stackoverflow.com/questions/1074212/how-to-show-the-sql-django-is-running Wenn es eine erhebliche Anzahl von Divisionen, aber nicht eine überwältigende Anzahl von Playoffs, kann es am besten sein nur um 'league.playoff_set.filter (double_elimination = True) abzufragen' und dann die Ergebnisse in Python zu gruppieren. z.B. http://stackoverflow.com/questions/31071888/python-group-list-items-in-a-dict –

Verwandte Themen