我正在构建动态过滤器,我将其通过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()?
答案 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>]