Django:准备查询但不执行它

dab*_*aba 0 django

我正在尝试在以下循环中使用 Django 进行一些有效的查询:

for division in divisions:
  playoffs = league.playoff_set.filter(division=division, double_elimination=True)
Run Code Online (Sandbox Code Playgroud)

我想也许playoffs在循环之前过滤,只选择那些double_elimination=True会增强它的:

playoffs = league.playoff_set.filter(double_elimination=True)
for division in divisions:
  division_playoffs = playoffs.filter(division=division)
Run Code Online (Sandbox Code Playgroud)

但是现在我担心这会playoffs在循环的每次运行中触发查询,而不是过滤先前检索到的结果。

它是按预期工作还是像我担心的那样工作?我应该使用它Q来构建这些性能更好的查询吗?

Ala*_*air 6

Django 查询集是惰性的。这意味着当您执行此操作时不会评估查询集

playoffs = league.playoff_set.filter(double_elimination=True)
Run Code Online (Sandbox Code Playgroud)

当您在循环中再次过滤查询集时,它甚至不会被评估。

division_playoffs = playoffs.filter(division=division)
Run Code Online (Sandbox Code Playgroud)

当您访问其内容(在视图或模板中)时,才会评估查询集。

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)
Run Code Online (Sandbox Code Playgroud)

因此,您的代码的两个版本的工作方式相同。你应该选择一个你认为更清楚的。