Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix identity search with only excludes or empty results #1013

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions api/mysagw/identity/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def get_search_terms(self, request):
if e.args[0] == "No closing quotation":
return self._split(f'{params}"')

def filter_queryset(self, request, queryset, view):
def filter_queryset(self, request, queryset, view): # noqa: C901
search_fields = self.get_search_fields(view, request)
search_terms = self.get_search_terms(request)

Expand Down Expand Up @@ -224,7 +224,7 @@ def filter_queryset(self, request, queryset, view):
if not membership_base_query.filter(
**{membership_orm_lookup: search_term},
).exists():
# short circuiting in order to save ~75% of processing time
# short-circuiting in order to save ~75% of processing time
continue

membership_subquery = membership_base_subquery.filter(
Expand All @@ -244,15 +244,23 @@ def filter_queryset(self, request, queryset, view):
filters.append(condition)

needed = [set(queryset.filter(f).values_list("pk", flat=True)) for f in filters]
needed_pks = reduce(lambda a, b: a.intersection(b), needed)
open-dynaMIX marked this conversation as resolved.
Show resolved Hide resolved

if needed == [set()]:
# if no records match our filters, we don't care about excludes
return models.Identity.objects.none()

excluded = [
pk
for f in excludes
for pk in queryset.filter(f).values_list("pk", flat=True)
]

queryset = queryset.filter(pk__in=needed_pks).exclude(pk__in=excluded)
if not needed:
# only excludes have been provided to the filter
queryset = queryset.exclude(pk__in=excluded)
else:
needed_pks = reduce(lambda a, b: a.intersection(b), needed)
queryset = queryset.filter(pk__in=needed_pks).exclude(pk__in=excluded)

if self.must_call_distinct(queryset, search_fields):
# Filtering against a many-to-many field requires us to
Expand Down
2 changes: 2 additions & 0 deletions api/mysagw/identity/tests/test_identity_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ def test_identity_set_interests(db, client, identity_factory, interest_factory):
('"philosophy class', [6]),
('"philosophy -class"', []),
("SAGW -winst", [1, 2, 3]),
("-example", [0]),
("nonexistent", []),
],
)
def test_identity_search(
Expand Down
Loading