2011-04-22 2 views
1

Я строит динамические фильтры, которые я прохожу мимо GET к QuerySet фильтра:Джанго 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) 

Так что я думаю, вопрос становится, как я могу создать

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

с помощью .filter()?

+0

Я принял первый ответ, так как это правильно, но это не исправить мою ошибку. В ** kwargs есть проблема с расширением, и я открыл новый вопрос об этом [здесь] (http://stackoverflow.com/questions/5762328/django-dynamic-filter-failure). Спасибо – selfsimilar

+0

Спасибо @ jammon и @DTing. Реальная проблема с этим заключалась в попытке передать логическое значение в GET. Он передавался через ** kwargs как строка «True», а не «True». Что работает, когда передается 'models.Student.objects.exclude (** kwargs)', так как 'True' оценивает 'True'. Но сопряжение не будет работать, так как «False» по-прежнему оценивает значение «True» при передаче в «models.Students.objects.filter (** kwargs)». Отсюда моя путаница. – selfsimilar

ответ

5

Возможно, я не понимаю вопроса. Но я вижу:

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

комментариев нет, голосов и принятого ответа ... могу ли я получить значок для этого или sth? –

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

отсутствует parenthese в аннотации, но изменения должны быть более 6 символов –

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>] 
Смежные вопросы