Remove remaining code for the old search method and the advanced search support, misc cleanups too

This commit is contained in:
Roberto Rosario
2012-04-12 12:59:06 -04:00
parent 2ee59df866
commit e89959b71b
9 changed files with 33 additions and 345 deletions

View File

@@ -15,17 +15,11 @@ from .models import IndexableObject
logger = logging.getLogger(__name__)
search = {'text': _(u'search'), 'view': 'search', 'famfam': 'zoom'}
#search_advanced = {'text': _(u'advanced search'), 'view': 'search_advanced', 'famfam': 'zoom_in'}
#search_again = {'text': _(u'search again'), 'view': 'search_again', 'famfam': 'arrow_undo'}
#register_sidebar_template(['search', 'search_advanced'], 'search_help.html')
register_sidebar_template(['search'], 'search_help.html')
#register_links(['search', 'search_advanced', 'results'], [search, search_advanced], menu_name='form_header')
register_links(['search'], [search], menu_name='form_header')
#register_links(['results'], [search_again], menu_name='sidebar')
#register_sidebar_template(['search', 'search_advanced', 'results'], 'recent_searches.html')
register_sidebar_template(['search'], 'recent_searches.html')
Document.add_to_class('mark_indexable', lambda obj: IndexableObject.objects.mark_indexable(obj))

View File

@@ -1,138 +0,0 @@
# original code from:
# http://www.julienphalip.com/blog/2008/08/16/adding-search-django-site-snap/
import re
import types
import datetime
from django.db.models import Q
from dynamic_search.conf.settings import LIMIT
registered_search_dict = {}
def register(model_name, model, title, fields):
registered_search_dict.setdefault(model_name, {'model': model, 'fields': [], 'title': title})
registered_search_dict[model_name]['fields'].extend(fields)
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(terms, 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.
"""
queries = []
for term in terms:
or_query = None
for field in search_fields:
if isinstance(field, types.StringTypes):
comparison = u'icontains'
field_name = field
elif isinstance(field, types.DictType):
comparison = field.get('comparison', u'icontains')
field_name = field.get('field_name', u'')
if field_name:
q = Q(**{'%s__%s' % (field_name, comparison): term})
if or_query is None:
or_query = q
else:
or_query = or_query | q
queries.append(or_query)
return queries
def perform_search(query_string, field_list=None):
model_list = {}
flat_list = []
result_count = 0
shown_result_count = 0
elapsed_time = 0
start_time = datetime.datetime.now()
search_dict = {}
if query_string:
simple_query_string = query_string.get('q', u'').strip()
if simple_query_string:
for model, values in registered_search_dict.items():
search_dict.setdefault(values['model'], {'query_entries': [], 'title': values['title']})
field_names = [field['name'] for field in values['fields']]
# One entry, single set of terms for all fields names
search_dict[values['model']]['query_entries'].append(
{
'field_name': field_names,
'terms': normalize_query(simple_query_string)
}
)
else:
for key, value in query_string.items():
try:
model, field_name = key.split('__', 1)
model_entry = registered_search_dict.get(model, {})
if model_entry:
for model_field in model_entry.get('fields', [{}]):
if model_field.get('name') == field_name:
search_dict.setdefault(model_entry['model'], {'query_entries': [], 'title': model_entry['title']})
search_dict[model_entry['model']]['query_entries'].append(
{
'field_name': [field_name],
'terms': normalize_query(value.strip())
}
)
except ValueError:
pass
for model, data in search_dict.items():
title = data['title']
queries = []
for query_entry in data['query_entries']:
queries.extend(get_query(query_entry['terms'], query_entry['field_name']))
model_result_ids = None
for query in queries:
single_result_ids = set(model.objects.filter(query).values_list('pk', flat=True))
#Convert queryset to python set and perform the
#AND operation on the program and not as a query
if model_result_ids == None:
model_result_ids = single_result_ids
else:
model_result_ids &= single_result_ids
if model_result_ids == None:
model_result_ids = []
result_count += len(model_result_ids)
results = model.objects.in_bulk(list(model_result_ids)[: LIMIT]).values()
shown_result_count += len(results)
if results:
model_list[title] = results
for result in results:
if result not in flat_list:
flat_list.append(result)
elapsed_time = unicode(datetime.datetime.now() - start_time).split(':')[2]
return {
'model_list': model_list,
'flat_list': flat_list,
'shown_result_count': shown_result_count,
'result_count': result_count,
'elapsed_time': elapsed_time
}

View File

@@ -1,45 +0,0 @@
from __future__ import absolute_import
from django import forms
from django.utils.translation import ugettext_lazy as _
from haystack.forms import SearchForm as BasicSearchForm
from .api import registered_search_dict
class SearchForm(BasicSearchForm):
pass
"""
class AdvancedSearchForm(SearchForm):
def __init__(self, *args, **kwargs):
super(AdvancedSearchForm, self).__init__(*args, **kwargs)
for model_name, values in registered_search_dict.items():
for field in values['fields']:
self.fields['%s__%s' % (model_name, field['name'])] = forms.CharField(
label=field['title'],
required=False
)
def search(self):
if not self.is_valid():
return self.no_query_found()
#if not self.cleaned_data.get('q'):
# return self.no_query_found()
for field in self.fields:
print 'field', field
#sqs = self.searchqueryset.auto_query(self.cleaned_data['q'])
if self.load_all:
sqs = sqs.load_all()
return sqs
def search(self):
sqs = super(ModelSearchForm, self).search()
return sqs.models(*self.get_models())
"""

View File

@@ -1,19 +1,19 @@
from __future__ import absolute_import
from urlparse import urlparse, parse_qs
from urllib import unquote_plus
from django.utils.simplejson import dumps, loads, JSONEncoder
from django.utils.simplejson import dumps
from django.db.models import Manager
from django.utils.http import urlencode
from django.contrib.auth.models import AnonymousUser
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from django.utils.encoding import smart_unicode, smart_str
from django.utils.encoding import smart_str
from dynamic_search.conf.settings import RECENT_COUNT
from .conf.settings import RECENT_COUNT
class RecentSearchManager(Manager):
def add_query_for_user(self, search_view):#user, url, hits):
def add_query_for_user(self, search_view):
query_dict = parse_qs(unquote_plus(smart_str(urlparse(search_view.request.get_full_path()).query)))
if query_dict and not isinstance(search_view.request.user, AnonymousUser):
@@ -35,13 +35,13 @@ class IndexableObjectManager(Manager):
return self.model.objects.filter(datetime__gte=datetime)
else:
return self.model.objects.all()
def get_indexables_pk_list(self, datetime=None):
return self.get_indexables(datetime).values_list('object_id', flat=True)
def mark_indexable(self, obj):
content_type = ContentType.objects.get_for_model(obj)
self.model.objects.get_or_create(content_type=content_type, object_id=obj.pk)
def clear_all(self):
self.model.objects.all().delete()

View File

@@ -1,14 +1,10 @@
from __future__ import absolute_import
import urlparse
import urllib
import datetime
from django.db import models
from django.utils.translation import ugettext as _
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.utils.encoding import smart_unicode, smart_str
from django.utils.translation import ugettext_lazy as _
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
@@ -16,7 +12,6 @@ from django.utils.simplejson import loads
from django.utils.http import urlencode
from .managers import RecentSearchManager, IndexableObjectManager
from .api import registered_search_dict
class RecentSearch(models.Model):
@@ -34,7 +29,6 @@ class RecentSearch(models.Model):
return self.form_string()
def form_string(self):
query = self.get_query()
if self.is_advanced():
return u'%s (%s)' % (self.get_query(), self.hits)
else:
@@ -64,16 +58,16 @@ class RecentSearch(models.Model):
class IndexableObject(models.Model):
"""
Store a list of object links that have been modified and are
meant to be indexed in the next search index update
Store a list of object links that have been modified and are
meant to be indexed in the next search index update
"""
datetime = models.DateTimeField(verbose_name=_(u'date time'))
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
objects = IndexableObjectManager()
def __unicode__(self):
return unicode(self.content_object)

View File

@@ -1,9 +1,7 @@
from __future__ import absolute_import
import datetime
import logging
from unidecode import unidecode
from haystack import indexes
from documents.models import Document
@@ -12,16 +10,6 @@ from .models import IndexableObject
logger = logging.getLogger(__name__)
'''
comment = models.TextField(blank=True, verbose_name=_(u'comment'))
checksum = models.TextField(blank=True, null=True, verbose_name=_(u'checksum'), editable=False)
page_label = models.CharField(max_length=32, blank=True, null=True, verbose_name=_(u'page label'))
page_number = models.PositiveIntegerField(default=1, editable=False, verbose_name=_(u'page number'), db_index=True)
{'name': u'documentversion__documentpage__content', 'title': _(u'Content')},
{'name': u'description', 'title': _(u'Description')},
'''
class DocumentIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)

View File

@@ -4,7 +4,8 @@ from django.core.urlresolvers import reverse
from django.template import Library
from django.utils.translation import ugettext as _
from ..forms import SearchForm
from haystack.forms import SearchForm
from ..models import RecentSearch
from ..conf.settings import RECENT_COUNT
@@ -27,21 +28,18 @@ def search_form(context):
@register.inclusion_tag('generic_subtemplate.html', takes_context=True)
def recent_searches_template(context):
try:
recent_searches = RecentSearch.objects.get_for_user(user=context['user'])
context.update({
'request': context['request'],
'STATIC_URL': context['STATIC_URL'],
'side_bar': True,
'title': _(u'recent searches (maximum of %d)') % RECENT_COUNT,
'paragraphs': [
u'<a href="%(url)s"><span class="famfam active famfam-%(icon)s"></span>%(text)s</a>' % {
'text': recent_search,
'url': recent_search.get_absolute_url(),
'icon': 'zoom_in' if recent_search.is_advanced() else 'zoom',
} for recent_search in recent_searches
]
})
return context
except Exception, e:
print 'EEEEEEEEEEEE', e
recent_searches = RecentSearch.objects.get_for_user(user=context['user'])
context.update({
'request': context['request'],
'STATIC_URL': context['STATIC_URL'],
'side_bar': True,
'title': _(u'recent searches (maximum of %d)') % RECENT_COUNT,
'paragraphs': [
u'<a href="%(url)s"><span class="famfam active famfam-%(icon)s"></span>%(text)s</a>' % {
'text': recent_search,
'url': recent_search.get_absolute_url(),
'icon': 'zoom_in' if recent_search.is_advanced() else 'zoom',
} for recent_search in recent_searches
]
})
return context

View File

@@ -6,7 +6,4 @@ from .views import CustomSearchView
urlpatterns = patterns('dynamic_search.views',
url(r'^$', CustomSearchView(form_class=SearchForm), (), 'search'),
#url(r'^advanced/$', CustomSearchView(form_class=AdvancedSearchForm), (), 'search_advanced'),
#url(r'^again/$', 'search_again', (), 'search_again'),
#url(r'^results/$', 'results', (), 'results'),
)

View File

@@ -1,21 +1,13 @@
from __future__ import absolute_import
import datetime
import urlparse
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils.translation import ugettext_lazy as _
from django.utils.http import urlencode
from django.contrib import messages
from django.conf import settings
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from haystack.views import SearchView
from common.utils import encapsulate
from dynamic_search.models import RecentSearch
from dynamic_search.api import perform_search
from .models import RecentSearch
class CustomSearchView(SearchView):
@@ -44,100 +36,8 @@ class CustomSearchView(SearchView):
'elapsed_time': unicode(datetime.datetime.now() - self.start_time).split(':')[2],
'object_list_object_name': 'object',
}
RecentSearch.objects.add_query_for_user(self)
context.update(self.extra_context())
return render_to_response(self.template, context, context_instance=self.context_class(self.request))
"""
def results(request, extra_context=None):
context = {}
context.update({
'query_string': request.GET,
#'hide_header': True,
'hide_links': True,
'multi_select_as_buttons': True,
'search_results_limit': LIMIT,
})
try:
response = perform_search(request.GET)
if response['shown_result_count'] != response['result_count']:
title = _(u'results, (showing only %(shown_result_count)s out of %(result_count)s)') % {
'shown_result_count': response['shown_result_count'],
'result_count': response['result_count']}
else:
title = _(u'results')
if extra_context:
context.update(extra_context)
query = urlencode(dict(request.GET.items()))
if query:
RecentSearch.objects.add_query_for_user(request.user, query, response['result_count'])
context.update({
'found_entries': response['model_list'],
'object_list': response['flat_list'],
'title': title,
'time_delta': response['elapsed_time'],
})
except Exception, e:
if settings.DEBUG:
raise
elif request.user.is_staff or request.user.is_superuser:
messages.error(request, _(u'Search error: %s') % e)
if SHOW_OBJECT_TYPE:
context.update({'extra_columns':
[{'name': _(u'type'), 'attribute': lambda x: x._meta.verbose_name[0].upper() + x._meta.verbose_name[1:]}]})
return render_to_response('search_results.html', context,
context_instance=RequestContext(request))
def search(request, advanced=False):
if advanced:
form = AdvancedSearchForm(data=request.GET)
return render_to_response('generic_form.html',
{
'form': form,
'title': _(u'advanced search'),
'form_action': reverse('results'),
'submit_method': 'GET',
'search_results_limit': LIMIT,
'submit_label': _(u'Search'),
'submit_icon_famfam': 'zoom',
},
context_instance=RequestContext(request)
)
else:
if request.GET.get('source') != 'sidebar':
# Don't include a form a top of the results if the search
# was originated from the sidebar search form
extra_context = {
'submit_label': _(u'Search'),
'submit_icon_famfam': 'zoom',
'form_title': _(u'Search'),
'form_hide_required_text': True,
}
if ('q' in request.GET) and request.GET['q'].strip():
query_string = request.GET['q']
form = SearchForm(initial={'q': query_string})
extra_context.update({'form': form})
return results(request, extra_context=extra_context)
else:
form = SearchForm()
extra_context.update({'form': form})
return results(request, extra_context=extra_context)
else:
# Already has a form with data, go to results
return results(request)
def search_again(request):
query = urlparse.urlparse(request.META.get('HTTP_REFERER', u'/')).query
return HttpResponseRedirect('%s?%s' % (reverse('search_advanced'), query))
"""