2011-04-22 49 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>]