I'm working on my first project and I'm attempting to implement a basic search function where users can search for a specific terms.
There are many options available, most a bit too heavy for what I require. I found this posting which illustrates how to implement a basic search function that sounds ideal:
The problem: the documentation is a bit incomplete, especially for a newbie. And I could use some help from those with experience on how to implement this.
The first action is to create a file within the project – say search.py – with the following code:
import re
from django.db.models import Q
def normalize_query(query_string,
findterms=re.compile(r'"([^"]+)"|(\S+)').findall,
normspace=re.compile(r'\s{2,}').sub):
''' Splits the query string in invidual keywords, getting rid of unecessary spaces
and grouping quoted words together.
Example:
>>> normalize_query(' some random words "with quotes " and spaces')
['some', 'random', 'words', 'with quotes', 'and', 'spaces']
'''
return [normspace(' ', (t[0] or t[1]).strip()) for t in findterms(query_string)]
def get_query(query_string, search_fields):
''' Returns a query, that is a combination of Q objects. That combination
aims to search keywords within a model by testing the given search fields.
'''
query = None # Query to search for every search term
terms = normalize_query(query_string)
for term in terms:
or_query = None # Query to search for a given term in each field
for field_name in search_fields:
q = Q(**{"%s__icontains" % field_name: term})
if or_query is None:
or_query = q
else:
or_query = or_query | q
if query is None:
query = or_query
else:
query = query & or_query
return query
Then the next step would be to import this file into the views – import search (not sure if the app name should proceed this). Then add this view, with the object detail changed to match my model:
def search(request):
query_string = ''
found_entries = None
if ('q' in request.GET) and request.GET['q'].strip():
query_string = request.GET['q']
entry_query = get_query(query_string, ['title', 'body',])
found_entries = Entry.objects.filter(entry_query).order_by('-pub_date')
return render_to_response('search/search_results.html',
{ 'query_string': query_string, 'found_entries': found_entries },
context_instance=RequestContext(request))
After this, I'm a bit stumped.
I assume this requires a basic url for the urls.py file, which seems straightforward enough. But I'm not sure how to place this within a template, what tags to use, etc. I have a search bar form on my main template page to which I would like to attach this. But returning the search/search_results.html template with the appropriate tags is a bit head scratching.
This is a fairly long post but if anyone could provide some insight on implementing this search function, it would be much appreciated. Thanks.