# -*- coding: utf-8 -*-
import re
from django.db.models import Q
from django.http import HttpResponseRedirect
from django.views.generic.list_detail import object_list
from django.views.generic.simple import direct_to_template
from journal.models import Post
from bistrot.models import Thought
from search.forms import SearchForm
# ``normalize_query`` and ``get_query methods`` come from this blog post
# http://www.julienphalip.com/blog/2008/08/16/adding-search-django-site-snap/
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
def search_redirect(request):
if 'search_terms' in request.REQUEST:
form = SearchForm(request.REQUEST)
if form.is_valid():
search_terms = [term for term in form.cleaned_data['search_terms'].split()]
return HttpResponseRedirect('/recherche/%s/' % ','.join(search_terms))
return HttpResponseRedirect('/')
def searchold(request, search_terms):
search_terms = search_terms.split(',')
post_queryset = Post.published.all()
for term in search_terms:
post_queryset = post_queryset.filter(Q(title__contains = term)
|Q(summary_html__contains = term)
|Q(content_html__contains = term))
thought_queryset = Thought.published.all()
for term in search_terms:
thought_queryset = thought_queryset.filter(Q(title__contains = term)
|Q(content_html__contains = term))
date_list = post_queryset.dates('publication_date', 'year')[::-1]
return direct_to_template(request, 'static/archives.html',
{
'post_list': post_queryset,
'thought_list': thought_queryset,
'date_list': date_list,
'search': True,
'search_terms': search_terms,
}
)
def search(request):
query_string = ''
found_entries = None
if ('q' in request.GET) and request.GET['q'].strip():
query_string = request.GET['q']
post_query = get_query(query_string, ['title', 'summary_html', 'content_html'])
post_queryset = Post.published.filter(post_query)
date_list = post_queryset.dates('publication_date', 'year')[::-1]
thought_query = get_query(query_string, ['title', 'content_html'])
thought_queryset = Thought.published.filter(thought_query)
return direct_to_template(request, 'static/archives.html',
{
'post_list': post_queryset,
'thought_list': thought_queryset,
'date_list': date_list,
'search': True,
'search_terms': normalize_query(query_string),
'query_string': query_string,
}
)
else:
#TODO: feedback?
return HttpResponseRedirect('/')