2011-04-22 45 views
1

我建立我路過得到一個查詢集過濾器的動態過濾器上的Django的queryset過濾器:空列表

for k, v in request.GET.iteritems(): 
    kwargs[str(k)] = str(v) 
students = models.Student.objects.filter(**kwargs) 

,它的工作,幾乎所有我在它拋出的疑問。但是,我有一個與多元關係相關的模型Group。所以一個學生可以成爲許多團體的成員。我能夠使用以下過濾屬於給定組的學生: 'groups__in='+str(group.id)

例如, - //example.com/students/?groups__in=1

但我不知道如何篩選不屬於任何組的學生。我試過以下沒有成功:

groups__in=None # students == [] 
groups__exact=None # students == [] 
groups__iexact=None # FAIL not that I really expected this to work 
groups__isnull=True # students == [] 

最後一個版本是我希望實際工作的。我相信我能得到這個通過修改上面的代碼類似

if request.GET['something']: 
    students = models.Student.objects.exclude(groups__isnull=False) 
else: 
    students = models.Student.objects.filter(**kwargs) 

所以我想問題就變成了工作,我怎麼能創建使用.filter

students = models.Student.objects.exclude(groups__isnull=False) 

()?

+0

我接受的第一反應,因爲它是正確的,但是這並沒有解決我的錯誤。 ** kwargs中存在擴展問題,並且我在此打開了一個新問題(http://stackoverflow.com/questions/5762328/django-dynamic-filter-failure)。謝謝 – selfsimilar 2011-04-23 05:14:19

+0

謝謝@jammon和@DTing。真正的問題是試圖在GET中傳遞布爾值。它是通過** kwargs作爲字符串「真」,而不是「真」。當傳遞給'models.Student.objects.exclude(** kwargs)'時,它會起作用,因爲'True'的計算結果爲'True'。但是這個結合將不起作用,因爲'False'在傳遞給'models.Students.objects.filter(** kwargs)'時仍然評估爲「True」。因此我的困惑。 – selfsimilar 2011-04-25 05:16:56

回答

5

也許我不明白這個問題。但我看到:

list(MyMod.objects.exclude(foo__isnull=False) 
) == list(MyMod.objects.filter(foo__isnull=True)) 
+4

沒有評論,反對票和接受的答案...我可以得到這個或某個徽章嗎? – 2011-04-26 15:06:51

0

我認爲models.Student.objects.filter(groups__isnull=True)應該做你想做的。 skyl指出,這與models.Student.objects.exclude(groups__isnull=False)相同。

這個解決方案有什麼問題?它可能在你的數據?作爲完整性檢查,您可以嘗試

from django.db.models import Count 
models.Student.objects.annotate(gcount=Count('groups').filter(gcount__gt=0) 

這應該會產生相同的結果。

和:
如果從客戶端採取不可信的數據,並餵它們選中到你的查詢,你應該仔細檢查你不打開一個安全漏洞的方式(或者說安全與您的數據的擔憂)。

+0

缺少註釋中的括號,但編輯應該超過6個字符 – 2016-04-24 20:25:41

0
students = models.Student.objects.filter(groups=None) 

下面是一些代碼,我已經躺在附近的例子:

# add collaborator with no organizations 
>>> john = Collaborator(first_name='John', last_name='Doe')       
>>> john.save() 
>>> john.organizations.all() 
[] 

# add another collaborator with no organizations 
>>> jane = Collaborator(first_name='Jane', last_name='Doe') 
>>> jane.save() 
>>> jane.organizations.all() 
[] 

# filter for collaborators with no collaborators 
>>> collabs_with_no_orgs = Collaborator.objects.filter(organizations=None) 
>>> collabs_with_no_orgs 
[<Collaborator: John Doe>, <Collaborator: Jane Doe>] 

# add organization to collaborator 
>>> jane.organizations = [Organization.objects.all()[0]] 
>>> jane.save() 
>>> jane.organizations.all() 
[<Organization: organization 1>] 

# filter for collaborators with no organizations 
>>> collabs_with_no_orgs = Collaborator.objects.filter(organizations=None) 
>>> collabs_with_no_orgs 
[<Collaborator: John Doe>]