Currently I have a very simple search option which goes through my pages and looks up through several fields for requested query. If I input a single word in it it works just fine, however if I input multiple words in search query, I get nothing, even if a single page contains all attributes. For example if I search for test admin
, I will not get empty query, even though there's a page with title test, with content test and author admin. Is there a way to expand the search to look up each word in search query individually?
# Fetch all pages and sort them alphabetically
queryset = Page.objects.all().filter(archived=False).order_by("title")
# Get search query if applicable
query = request.GET.get("q")
if query:
queryset = queryset.filter(
Q(title__icontains=query) |
Q(content__icontains=query) |
Q(user__username__icontains=query) |
Q(user__first_name__icontains=query) |
Q(user__last_name__icontains=query)
).distinct()
You're asking for something like the following, where you filter by each individual word in the query:
import operator
queryset = Page.objects.all().filter(archived=False).order_by("title")
query = request.GET.get("q")
if query:
words = query.split()
fields = ["title__icontains", "content__icontains", "user__username__contains",
"user__first_name__icontains", "user__last_name__icontains"]
q_expression = [Q(f,w) for f in fields for w in words]
queryset = queryset.filter(reduce(operator.or_, q_expression))\
.distinct()
However, at this point doing search this way gets a little bit messy. If your app grows and you need to search over several models, consider looking into an external search package such as Haystack.