2015-03-31 81 views
2

我有以下代碼:意外行爲查詢集

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

我希望第一和第三打印的這個結果是eqaul但他們not.How這可能是發生?

+0

那麼結果呢? – Kasramvd 2015-03-31 15:40:57

+0

看來** len(foo_list)**後foo_list的值發生變化,所以list的第一個元素的id不同。 – 2015-03-31 15:43:55

+0

幸運的是,亞歷克斯完成了這項工作! ;) – Kasramvd 2015-03-31 15:48:38

回答

4

你在https://code.djangoproject.com/ticket/9006跑步進入 「wontfix」 的問題 -

LIMIT查詢沒有ORDER BY不能保證返回一致 結果

(取決於底層設置數據庫引擎),這就是你的[0]索引造成的 - 因爲儘管誤導性名稱foo_list而不是的一個列表,它的查詢集本身!截至https://docs.djangoproject.com/en/1.7/ref/models/querysets/記載,

切片的未計算QuerySet通常返回另一個未計算 QuerySet

解決方案:使它的列表:

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

後生活幸福快樂的日子: - )

0

原因是querysets are lazy

當您在第一行中構造foo_list時,數據庫上沒有任何反應。在實際從查詢集中獲取對象之前,不會執行該查詢。

所以,當你得到foo_list[0].id首次,你居然重新切片它,從而運行SELECT聲明要求單行。現在,當您撥打len(foo_list)時,您的強制原始查詢集(它將返回100行)執行。

由於您運行兩個不同的查詢(一個用於單個行,一個用於100個行)並且未指定order_by子句,因此這兩個查詢可能(並且會)返回不同的結果。