2010-06-13 55 views
27

我有時需要確保某些實例從查詢集中排除。
這是我經常這樣做的方式:Django從查詢集中排除特定實例而不使用字段查找

unwanted_instance = MyModel.objects.get(pk=bad_luck_number) 
uninteresting_stuff_happens() 
my_results = MyModel.objects.exclude(id=unwanted_instance.id) 

,或者,如果我有更多的人:

my_results = MyModel.objects.exclude(id_in=[uw_in1.id, uw_in2.id, uw_in3.id]) 

這種 '感覺' 有點笨重,所以我嘗試:

my_ideally_obtained_results = MyModel.objects.exclude(unwanted_instance) 

哪一個不行。但我讀here on SO子查詢可以用作排除參數。
我運氣不好嗎?我錯過了一些功能(檢查文檔,但沒有找到任何有用的指針)

回答

61

你已經這樣做的方式是最好的方法。

如果這是一個模型不可知的方式來做到這一點,你正在尋找,不要忘記,你可以做query.exclude(pk=instance.pk)

正如順便說一句,如果 Django的ORM有一個身份映射器(它目前並沒有),那麼你就能夠做到像MyModel.objects.filter(<query>).all().remove(<instance>),但你的運氣在這方面。你這樣做的方式(或上面的那個)是你擁有的最好的方式。

哦,你也可以做的比這in查詢與列表理解好得多:query.exclude(id__in=[o.id for o in <unwanted objects>])

+3

另外,如果你有個要排除的查詢集(例如'MyModel.objects.filter()'),你可以使用'ValuesQuerySet'來獲取id: 'id_dicts = MyModel.objects.filter()。values('id ')'然後 'query.exclude(id__in = [item ['id'] for item in id_dicts])''。 – 2013-11-18 00:11:51

+2

差不多4年後,這個答案解決了我的問題。 :-) – Garfonzo 2014-03-18 18:48:21

+2

我只是想給@ RacingTadpole的建議添加一些內容:您可以輕鬆使用'values_list(「id」,flat = True)'獲取所有ID的順序列表。然而,這會碰到數據庫,所以我建議使用Python的列表理解。 – stschindler 2014-07-04 10:13:34

3

提供的答案是完美的,試試這個這對我來說工作正常

步驟1)

from django.db.models import Q 

步驟2)

MyModel.objects.filter(~Q(id__in=[o.id for o in <unwanted objects>])) 
+9

如何使用'Q'表達式比'.exclude(id_in = [o.id for o in <不想要的對象>])'更好? – lanzz 2014-03-12 13:40:51

+0

這是另一種替代解決方案,以實現相同 – kartheek 2014-03-13 06:30:13

+0

這似乎是一個非常低效的選擇。 – 2017-07-29 23:13:44

相關問題