Django Queryset过滤空列表

时间:2011-04-22 21:48:23

标签: django filter many-to-many

我正在构建动态过滤器,我将其通过GET传递给查询集过滤器:

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

它正在为我投掷的几乎所有查询工作。但是,我有一个相关的模型,有很多关系,Group。因此,学生可以成为许多团体的成员。我可以使用以下内容过滤属于特定组的学生: “groups__in='+str(group.id)

e.g。 --//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 )

所以我想问题就变成了,我怎么能创造

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

使用.filter()?

3 个答案:

答案 0 :(得分:5)

也许我不明白这个问题。但我明白了:

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

答案 1 :(得分: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)

应该产生相同的结果。

和:
如果您从客户端获取不可靠的数据并将其取消选中,则应仔细检查您是否未以这种方式打开安全漏洞(或者您的数据不关心安全性)。

答案 2 :(得分: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>]