Reputation: 35
so on the way of learning process, I am making my first side-project on django.
I want to make my search more accurate, for example: when post body contains text with 3 words "I love stackoverflow" and someone searches for "I stackoverflow" (without word LOVE), result is not shown on the search page.
What could be the best approach in this case to get the result, even if the post body does not contain words in that order as a search query?
views.py
def search(request):
posts = Post.objects.all().order_by('title')
query = request.GET.get('q')
print(query)
if query:
posts = Post.objects.filter(
Q(title__icontains=query)|
Q(body__icontains=query)
)
context = {
"posts": posts,
}
return render(request, "search.html", context)
Upvotes: 0
Views: 470
Reputation: 1343
Try to split your query
from itertools import chain
def search(request):
posts = Post.objects.all().order_by('title')
query = request.GET.get('q')
if query:
words = query.split(" ")
results = []
for word in words:
match = posts.filter(
Q(title__icontains=word)|
Q(body__icontains=word)
)
if match:
results.append(match)
posts = set(chain(*results))
context = {
"posts": posts,
}
return render(request, "search.html", context)
Upvotes: 0
Reputation: 906
I'd recommend using full text search with django haystack with any search engine. But, to respond to your case, something like following would do the trick, though is not very optimised:
from django.db.models import Q
# consider only words which are having a length greater than 2
# also, words should be sanitised and cleaned before using for db queries.
# use a form for that.
parts = [i for i in request.GET.get('q').split(' ') if len(i) >= 3]
qs = Q()
query = [qs | Q(title__icontains=query) | Q(body__icontains=query) for q in parts]
result = Post.objects.filter(query).order_by().distinct()
Upvotes: 1
Reputation: 1003
Django provides multiple efficient ways to search on a postgreSQL database that you can find on the official docs.
Upvotes: 0