Skip to content

Commit

Permalink
fix: generalizes player search query format
Browse files Browse the repository at this point in the history
Prior to this commit, the search query was used monolithically as a
single string to match the members' member id or their (comma-separated)
full name;  this had many shortcomings, e.g., a search query " 12345 "
would fail to match a member with id "12345", and a search query
"surname name" would fail to match a member with full name "surname,
name".  Also see usgo#164 and usgo#248.

In this commit, the search is first stripped of outer whitespace, which
helps search for member ids.  If the search query is not an id, then the
search query is split into tokens, and a match with a member is found if
all of the respective query tokens match the member's full name.  This
allows users to run queries such as "name", "surname", "name surname" or
"surname name".
  • Loading branch information
abaisero committed Apr 5, 2022
1 parent 0198fdd commit 78d404e
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions agagd/agagd_core/views/search.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import functools
import operator

from agagd_core.models import Member
from agagd_core.tables.search import SearchResultsTable
from django.db.models import F, Q
Expand All @@ -13,7 +16,7 @@ class SearchView(DetailView):
search_results_template_name = "search_results.html"

def get(self, request):
query = request.GET.get("q", "")
query = request.GET.get("q", "").strip()

if not query:
return TemplateResponse(request, self.template_name)
Expand All @@ -22,9 +25,14 @@ def get(self, request):
member_id = [int(query)]
return HttpResponseRedirect(reverse("players_profile", args=member_id))

# constructing intersection queryset from query tokens
tokens = query.split()
querysets = (Q(full_name__icontains=token) for token in tokens)
queryset = functools.reduce(operator.and_, querysets)

member_table_data = (
Member.objects.filter(Q(member_id=F("players__pin_player")))
.filter(full_name__icontains=query)
.filter(queryset)
.values(
"member_id",
"chapter_id",
Expand Down

0 comments on commit 78d404e

Please sign in to comment.