Python django queryset中的意外行为
我有以下代码:Python django queryset中的意外行为,python,django,django-queryset,Python,Django,Django Queryset,我有以下代码: foo_list = Foo.objects.all()[100:200] print foo_list[0].id print len(foo_list) print foo_list[0].id 我希望第一次和第三次打印的结果是一样的,但事实并非如此。这怎么可能发生呢?您在-- 没有ORDER BY的LIMIT查询不能保证返回一致的 结果集 (取决于底层数据库引擎),这就是您的[0]索引导致的情况——因为尽管有误导性的名称foo_list是不是列表,但它本身就是querys
foo_list = Foo.objects.all()[100:200]
print foo_list[0].id
print len(foo_list)
print foo_list[0].id
我希望第一次和第三次打印的结果是一样的,但事实并非如此。这怎么可能发生呢?您在--
没有ORDER BY的LIMIT查询不能保证返回一致的
结果集
(取决于底层数据库引擎),这就是您的[0]
索引导致的情况——因为尽管有误导性的名称foo_list
是不是列表,但它本身就是queryset!如文件所述
切片一个未计算的QuerySet
通常会返回另一个未计算的
QuerySet
解决方案:将其列为一个列表:
foo_list = list(Foo.objects.all()[100:200])
从此过上幸福的生活:-)原因是
当您在第一行中构建foo_列表时,数据库中不会发生任何事情。直到您从queryset中实际获取一个对象,查询才会执行
因此,当您第一次获得foo_列表[0].id
时,实际上是对它进行了重新切片,从而运行SELECT
语句,要求获得一行。现在,当您调用len(foo_list)
时,您将强制执行原始queryset(返回100行)
由于您运行了两个不同的查询(一个用于单行,一个用于100行),并且没有指定order\u by
子句,这两个查询可能(并且确实)返回不同的结果。那么结果如何?似乎在**len(foo\u list)**foo\u list的值发生变化之后,所以列表第一个元素的id不同。幸运的是Alex完成了这项工作!;)