2013-02-15 52 views
0

在官方的Django文檔,部分來自查詢集排除(https://docs.djangoproject.com/en/dev/ref/models/querysets/#exclude),有幾個查詢的解釋:Django文檔錯誤?

這個例子中排除其PUB_DATE晚於2005-1-3,其標題是「你好」的所有條目:

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello') 

在SQL方面,計算結果爲:

SELECT ... 
WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello') 

這個例子中排除其PUB_DATE晚於2005-1-3或者其標題是「Hello」的所有條目:

Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello') 

在SQL術語,計算結果爲:

SELECT ... 
WHERE NOT pub_date > '2005-1-3' 
AND NOT headline = 'Hello' 

注意第二個例子是更限制性的。

最後一個不清楚。我沒有看到第一個和第二個之間的區別,任何人都可以解釋這一點嗎?

回答

0

如果你指的是部分「注意第二個例子是更多的限制。」,或許更多地以數學方法可以幫助你:

NOT (pub_date > '2005-1-3' AND headline = 'Hello')

可以翻譯成:

NOT pub_date > '2005-1-3' OR NOT headline = 'Hello'

相比之下:

NOT pub_date > '2005-1-3' AND NOT headline = 'Hello'

限制性較小,因爲您希望OR的任一部分爲真,即 - A OR BA AND B限制性更小。

回到文檔,在第一種情況下,您排除那些同時適合這兩個限制的人。在第二種情況下,排除那些符合第一種限制的人,並排除那些符合第二種限制的人,即排除那些符合任何一種限制的人。

@OP的評論:想象一下,我們有四項AA,AB,BB和CC。如果我們說:

Item.objects.filter(name_startswith='A', name_endswith='B') 

結果將是{AB}。當然,如果我們說:

Item.objects.exclude(name_startswith='A', name_endswith='B') 

結果將是{AA,BB,CC},因爲我們只想排除那些誰與「A」開始,用「B」結束。下一個:

Item.objects.exclude(name_startswith='A') 

將導致{BB,CC}。然而,當我們另一個排除:

Item.objects.exclude(name_startswith='A').exclude(name_endswith='B') 

我們實際上是在說THE_RESULT_OF_THE_FIRST_EXCLUDE.exclude(name_endswith='B')。那就是:

{BB, CC}.exclude(name_endswith='B') 

哪個會返回{CC}。不像filter,其中

Item.objects.filter(<condition_1>).filter(<condition_2>) 

熊一樣的結果:

Item.objects.filter(<condition_1>, <condition_2>) 

排除的是。它類似於布爾操作:

NOT(A和B)=不是一非B NOT(A或B)= NOT A非B

+0

THX的答案,然後是另一個問題:爲什麼是Entry.objects.exclude(pub_date__gt = datetime.date(2005,1,3))。exclude(headline ='Hello')等於SELECT ... WHERE NOT pub_date>'2005-1-3' AND不是標題='你好',我不能真正理解爲什麼在SQL中有AND,而不是OR? – 2013-02-15 14:57:10

+0

看看我的編輯。希望這可以幫助 :) – dmg 2013-02-15 15:42:58

1

第一個示例創建一個嵌套的子表達式,而第二個示例創建兩個單獨的表達式。