Фильтр запросов Django в пустом списке - PullRequest
1 голос
/ 23 апреля 2011

Я создаю динамические фильтры, которые я передаю GET фильтру наборов запросов:

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

, и он работает почти для всех запросов, которые я к нему добавляю.Тем не менее, у меня есть родственная модель с множеством отношений, группа.Таким образом, студент может быть членом многих групп.Я могу отфильтровать студентов, которые принадлежат к определенной группе, используя следующее: '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()

Ответы [ 3 ]

5 голосов
/ 23 апреля 2011

Может быть, я не понимаю вопроса. Но я вижу:

list(MyMod.objects.exclude(foo__isnull=False)
) == list(MyMod.objects.filter(foo__isnull=True))
0 голосов
/ 23 апреля 2011
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>]
0 голосов
/ 23 апреля 2011

Я думаю models.Student.objects.filter(groups__isnull=True) должен делать то, что вы хотите.Как отметил Скайл, это то же самое, что и models.Student.objects.exclude(groups__isnull=False).

В чем проблема с этим решением?Может ли это быть в ваших данных?В качестве проверки работоспособности вы можете попробовать

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

, который должен дать те же результаты.

И:
Если вы берете ненадежные данные от клиента и не проверяете их в своем запросе,вам следует дважды проверить, что вы не открываете дыру в безопасности таким образом (или что безопасность не имеет значения для ваших данных).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...