Django 查询集中的意外行为

Unexpected behaviour in django queryset

我有以下代码:

foo_list = Foo.objects.all()[100:200]
print foo_list[0].id
print len(foo_list)
print foo_list[0].id

我希望第一次和第三次打印的结果相等,但它们是 not.How 这可能发生吗?

您 运行 进入了 https://code.djangoproject.com/ticket/9006 的 "wontfix" 问题 --

LIMIT queries without ORDER BY aren't guaranteed to return consistent result sets

(取决于底层数据库引擎),这就是您的 [0] 索引导致发生的原因——因为尽管名称 foo_list 具有误导性,但 不是 一个列表,它本身就是查询集!如 https://docs.djangoproject.com/en/1.7/ref/models/querysets/ 中所述,

Slicing an unevaluated QuerySet usually returns another unevaluated QuerySet

解决方案:将其设为列表:

foo_list = list(Foo.objects.all()[100:200])

从此过上幸福的生活:-)

原因是querysets are lazy.

当你在第一行构造你的 foo_list 时,数据库没有任何反应。在您实际从查询集中获取对象之前,不会执行查询。

所以,当你第一次得到 foo_list[0].id 时,你实际上 重新切片它 ,因此 运行 宁一个 SELECT要求一行的语句。现在,当您调用 len(foo_list) 时,您 强制 执行原始查询集(returns 100 行)。

由于您 运行 两个不同的查询(一个用于单行,一个用于 100 行)并且没有指定 order_by 子句,这两个查询可能(并且确实)return 不同的结果。