Django Shell 在任何位置索引查询集 returns 完全相同的结果 - DB Lazy Evaluation

Django Shell indexing Queryset on any position returns the exact same result - DB Lazy Evaluation

这可能不是一个问题,因为它是一个确认和请求更多见解

当 运行 python 中的 QuerySet 请求时 shell 是这样的:

qs = MyModel.objects.all()qs = MyModel.objects.get_queryset()qs = MyModel.objects.filter(field='something')

然后是这样的东西:qs[0]qs[1]qs[any_valid_int] 它总是 return return 位置 0 的数据库条目ed QuerySet 无论您使用什么索引。起初这让我挠头。现在我明白了 QuerySets 是 Django 中的生成器(?)并且 被评估为惰性 如此处记录:Django Doc: Querysets Are Lazy

当你做任何事情(在 shell 中)评估 returned qs 例如 len(qs) 然后再次使用索引它会突然 return 正确的数据库条目 qs[any_valid_int] 的行为完全符合预期。我相信这也与此 Django bug report question from 6 years ago 相对应。

假设这与惰性求值有关,那么我是否走在正确的轨道上?在 Django shell 中,best/quick 的方法是什么,只需获取一个 QuerySet 并直接索引您想要的 进行测试,而不必使用 [=19 之类的东西=] 首先?是否甚至可以像那样使用直接索引,或者您是否已经遍历它们/进一步过滤 QuerySet 等?谢谢

So am I on the right track here assuming that this has to do with lazy evaluation?

。如果您有一个 未评估的 查询集 qs,并且您使用 qs[<i>i</i>] 进行查询,它会生成一个如下所示的查询:

SELECT …
FROM …
WHERE …
LIMIT 1 OFFSET i

但是如果不指定ORDER BY …,那么数据库可以return任意顺序记录,因此第一次查询中位置0的item,可以是在第二个查询的位置 3,因此可能导致 qs[0]qs[1] return 相同的项目。

如果您使用 len(qs)list(qs) 或任何将数据加载到查询集中的方法,那么 qs[0] 而不是 对数据库的额外查询:它已经在缓存中有记录,这意味着它将 return 查询集缓存中特定位置的项目,并且由于记录已经 return 以特定顺序编辑,无论该顺序是什么,qs[0]qs[1] 因此是由数据库编辑的不同记录 return。