diff options
author | Paul Eggleton <paul.eggleton@linux.intel.com> | 2013-02-19 15:54:43 +0000 |
---|---|---|
committer | Paul Eggleton <paul.eggleton@linux.intel.com> | 2013-02-19 17:22:45 +0000 |
commit | 430ae4f90e8953a0f1c91842bb2eb291ab9b92df (patch) | |
tree | 19f102279ea00cd1fda502787fdc052f275bce91 | |
parent | fd600fb716ce46a0f73ca0017f1923fba6cb53ef (diff) | |
download | openembedded-core-contrib-430ae4f90e8953a0f1c91842bb2eb291ab9b92df.tar.gz |
Improve recipe search
* Use more traditional GET instead of POST method
* Search in pn, summary, description and filename instead of just pn
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
-rw-r--r-- | README | 3 | ||||
-rw-r--r-- | layerindex/recipes.html | 5 | ||||
-rw-r--r-- | layerindex/simplesearch.py | 39 | ||||
-rw-r--r-- | layerindex/views.py | 16 |
4 files changed, 50 insertions, 13 deletions
@@ -91,5 +91,6 @@ Bundled jQuery is redistributed under the MIT license. Bundled uitablefilter.js is redistributed under the MIT license. All other content is copyright (C) 2013 Intel Corporation and licensed -under the MIT license - see COPYING.MIT for details. +under the MIT license (unless otherwise noted) - see COPYING.MIT for +details. diff --git a/layerindex/recipes.html b/layerindex/recipes.html index a51831d25c..72021b0aee 100644 --- a/layerindex/recipes.html +++ b/layerindex/recipes.html @@ -31,9 +31,8 @@ <div class="row-fluid"> <div class="input-append"> - <form id="filter-form" action="{% url recipe_search %}" method="post"> - {% csrf_token %} - <input type="text" class="input-xxlarge" id="appendedInputButtons" placeholder="Search recipes" name="filter" value="{{ search_keyword }}" /> + <form id="filter-form" action="{% url recipe_search %}" method="get"> + <input type="text" class="input-xxlarge" id="appendedInputButtons" placeholder="Search recipes" name="q" value="{{ search_keyword }}" /> <button class="btn" type="submit">search</button> </form> </div> diff --git a/layerindex/simplesearch.py b/layerindex/simplesearch.py new file mode 100644 index 0000000000..3b2a530716 --- /dev/null +++ b/layerindex/simplesearch.py @@ -0,0 +1,39 @@ +# Borrowed from http://julienphalip.com/post/2825034077/adding-search-to-a-django-site-in-a-snap +# Copyright 2011 Julien Phalip. All Rights Reserved. + +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 diff --git a/layerindex/views.py b/layerindex/views.py index a96ec40f49..eca6472499 100644 --- a/layerindex/views.py +++ b/layerindex/views.py @@ -19,6 +19,7 @@ from django.db.models import Q from django.core.mail import EmailMessage from django.template.loader import get_template from django.template import Context +import simplesearch import settings @@ -96,22 +97,19 @@ class LayerListView(ListView): class RecipeSearchView(ListView): context_object_name = 'recipe_list' - paginate_by = 20 + paginate_by = 10 def get_queryset(self): - keyword = self.request.session.get('keyword') - if keyword: - return Recipe.objects.all().filter(pn__icontains=keyword).order_by('pn', 'layer') + query_string = self.request.GET.get('q', '') + if query_string.strip(): + entry_query = simplesearch.get_query(query_string, ['pn', 'summary', 'description', 'filename']) + return Recipe.objects.filter(entry_query).order_by('pn', 'layer') else: return Recipe.objects.all().order_by('pn', 'layer') - def post(self, request, *args, **kwargs): - request.session['keyword'] = request.POST['filter'] - return HttpResponseRedirect(reverse('recipe_search')) - def get_context_data(self, **kwargs): context = super(RecipeSearchView, self).get_context_data(**kwargs) - context['search_keyword'] = self.request.session.get('keyword') or '' + context['search_keyword'] = self.request.GET.get('q', '') return context |