X-Git-Url: http://git.ithinksw.org/philo.git/blobdiff_plain/cc6dbd55a2af538657c288a709662b9c84949854..f5ef756179b62eb9a87983936c2576586632d8d7:/philo/contrib/sobol/models.py diff --git a/philo/contrib/sobol/models.py b/philo/contrib/sobol/models.py index 7687c09..ffe5871 100644 --- a/philo/contrib/sobol/models.py +++ b/philo/contrib/sobol/models.py @@ -11,7 +11,7 @@ from django.http import HttpResponseRedirect, Http404, HttpResponse from django.utils import simplejson as json from django.utils.datastructures import SortedDict -from philo.contrib.sobol import registry +from philo.contrib.sobol import registry, get_search_instance from philo.contrib.sobol.forms import SearchForm from philo.contrib.sobol.utils import HASH_REDIRECT_GET_KEY, URL_REDIRECT_GET_KEY, SEARCH_ARG_GET_KEY, check_redirect_hash, RegistryIterator from philo.exceptions import ViewCanNotProvideSubpath @@ -79,6 +79,8 @@ class Search(models.Model): self._favored_results += subresults else: break + if len(self._favored_results) == len(results): + self._favored_results = [] return self._favored_results class Meta: @@ -151,32 +153,20 @@ class Click(models.Model): get_latest_by = 'datetime' -class RegistryChoiceField(SlugMultipleChoiceField): - def _get_choices(self): - if isinstance(self._choices, RegistryIterator): - return self._choices.copy() - elif hasattr(self._choices, 'next'): - choices, self._choices = itertools.tee(self._choices) - return choices - else: - return self._choices - choices = property(_get_choices) - - try: from south.modelsinspector import add_introspection_rules except ImportError: pass else: - add_introspection_rules([], ["^philo\.contrib\.shipherd\.models\.RegistryChoiceField"]) + add_introspection_rules([], ["^philo\.contrib\.sobol\.models\.RegistryChoiceField"]) class SearchView(MultiView): """Handles a view for the results of a search, anonymously tracks the selections made by end users, and provides an AJAX API for asynchronous search result loading. This can be particularly useful if some searches are slow.""" #: :class:`ForeignKey` to a :class:`.Page` which will be used to render the search results. results_page = models.ForeignKey(Page, related_name='search_results_related') - #: A :class:`.SlugMultipleChoiceField` whose choices are the contents of the :class:`.SearchRegistry` - searches = RegistryChoiceField(choices=registry.iterchoices()) + #: A :class:`.SlugMultipleChoiceField` whose choices are the contents of :obj:`.sobol.search.registry` + searches = SlugMultipleChoiceField(choices=registry.iterchoices()) #: A :class:`BooleanField` which controls whether or not the AJAX API is enabled. #: #: .. note:: If the AJAX API is enabled, a ``ajax_api_url`` attribute will be added to each search instance containing the url and get parameters for an AJAX request to retrieve results for that search. @@ -206,10 +196,6 @@ class SearchView(MultiView): ) return urlpatterns - def get_search_instance(self, slug, search_string): - """Returns an instance of the :class:`.BaseSearch` subclass corresponding to ``slug`` in the :class:`.SearchRegistry` and instantiated with ``search_string``.""" - return registry[slug](search_string.lower()) - def results_view(self, request, extra_context=None): """ Renders :attr:`results_page` with a context containing an instance of :attr:`search_form`. If the form was submitted and was valid, then one of two things has happened: @@ -245,11 +231,12 @@ class SearchView(MultiView): search_instances = [] for slug in self.searches: - search_instance = self.get_search_instance(slug, search_string) - search_instances.append(search_instance) + if slug in registry: + search_instance = get_search_instance(slug, search_string) + search_instances.append(search_instance) - if self.enable_ajax_api: - search_instance.ajax_api_url = "%s?%s=%s" % (self.reverse('ajax_api_view', kwargs={'slug': slug}, node=request.node), SEARCH_ARG_GET_KEY, search_string) + if self.enable_ajax_api: + search_instance.ajax_api_url = "%s?%s=%s" % (self.reverse('ajax_api_view', kwargs={'slug': slug}, node=request.node), SEARCH_ARG_GET_KEY, search_string) if eventlet and not self.enable_ajax_api: pool = eventlet.GreenPool() @@ -258,8 +245,16 @@ class SearchView(MultiView): pool.waitall() context.update({ - 'searches': search_instances + 'searches': search_instances, + 'favored_results': [] }) + + try: + search = Search.objects.get(string=search_string) + except Search.DoesNotExist: + pass + else: + context['favored_results'] = [r.url for r in search.get_favored_results()] else: form = SearchForm() @@ -270,8 +265,10 @@ class SearchView(MultiView): def ajax_api_view(self, request, slug, extra_context=None): """ - Returns a JSON string containing two keyed lists. + Returns a JSON object containing the following variables: + search + Contains the slug for the search. results Contains the results of :meth:`.Result.get_context` for each result. rendered @@ -279,19 +276,19 @@ class SearchView(MultiView): hasMoreResults ``True`` or ``False`` whether the search has more results according to :meth:`BaseSearch.has_more_results` moreResultsURL - Contains None or a querystring which, once accessed, will note the :class:`Click` and redirect the user to a page containing more results. + Contains ``None`` or a querystring which, once accessed, will note the :class:`Click` and redirect the user to a page containing more results. """ search_string = request.GET.get(SEARCH_ARG_GET_KEY) - if not request.is_ajax() or not self.enable_ajax_api or slug not in self.searches or search_string is None: + if not request.is_ajax() or not self.enable_ajax_api or slug not in registry or slug not in self.searches or search_string is None: raise Http404 - search_instance = self.get_search_instance(slug, search_string) + search_instance = get_search_instance(slug, search_string) return HttpResponse(json.dumps({ + 'search': search_instance.slug, 'results': [result.get_context() for result in search_instance.results], - 'rendered': [result.render() for result in search_instance.results], - 'hasMoreResults': search.has_more_results(), - 'moreResultsURL': (u"?%s" % search.more_results_querydict.urlencode()) if search.more_results_querydict else None, + 'hasMoreResults': search_instance.has_more_results, + 'moreResultsURL': search_instance.more_results_url, }), mimetype="application/json") \ No newline at end of file