2010-03-11 135 views
19

django中的過濾器和排除之間有區別嗎?如果我有Django過濾器vs排除

self.get_query_set().filter(modelField=x) 

我想添加另一個標準,在跟隨兩行代碼之間是否有意義的區別?

self.get_query_set().filter(user__isnull=False, modelField=x) 

self.get_query_set().filter(modelField=x).exclude(user__isnull=True) 

是一種被認爲是更好的做法還是它們在功能和性能上都一樣?

回答

16

這兩個都是懶洋洋的評價,所以我希望他們執行等效。 SQL可能不同,但沒有真正的區別。

+0

謝謝。所以這只是個人喜好的問題?我只是想確保我不會做一些莫名其妙的愚蠢行爲。 – Enrico 2010-03-11 17:11:22

+2

@Enrico:不是,它取決於你想要的。看到我的答案。在這種情況下,性能並不重要,它們是兩種用於不同目的的方法。對於SQL生成,文檔中提到'.exclude()':*在底層SQL語句中通過AND連接了多個參數,並且整個事件都包含在NOT()。* – 2010-03-11 17:26:04

+0

@Felix中。謝謝。我想我的主要問題 - 我可以更清楚地傳達的是關於django和SQL最終的表現。從您的後續評論中,聽起來好像其中一個可能比另一個更好,但主要基於生成的SQL。但是,將第二個語句更改爲'.exclude(user__isnull = True).filter(modelField = x)'會使兩個語句再次相同。 – Enrico 2010-03-13 18:13:14

15

一般排除是過濾器的對立面。在這種情況下,兩個例子都是一樣的。

這裏:

self.get_query_set().filter(user__isnull=False, modelField=x) 

您選擇相應的字段用戶不爲空項,modelField具有值x

在這種情況下:

self.get_query_set().filter(modelField=x).exclude(user__isnull=True) 

首先,你選擇條目modelField具有價值x(null和user中的用戶都不爲null),則排除具有字段用戶null的條目。

我認爲在這種情況下,它會更好地使用第一個選項,它看起來更清潔。但兩者工作都一樣。

9

這取決於你想達到什麼。使用布爾值可以很容易地在.exclude().filter()之間切換,但是關於例如如果你想獲得除3月份以外的所有文章?您可以編寫查詢作爲

Posts.objects.exclude(date__month=3) 

隨着.filter()這將是(但我不知道是否實際工作):

Posts.objects.filter(date__month__in=[1,2,4,5,6,7,8,9,10,11,12]) 

,或者你將不得不使用一個Q對象。

由於函數名已經暗示,.exclude()用於排除結果集中的數據集。對於布爾值,您可以輕鬆地將其反轉,並使用.filter()來代替,但對於其他值,這可能會更棘手。