def view(self, request, content_type, pk): """The view for showing the results of a single item in the Haystack index. :param request: the current request. :type request: WSGIRequest :param content_type: ``app_label`` and ``model_name`` as stored in Haystack, separated by "." :type content_type: string. :param pk: the object identifier stored in Haystack :type pk: string. :return: A template rendered into an HttpReponse """ if not self.has_change_permission(request, None): raise PermissionDenied query = {DJANGO_ID: pk, DJANGO_CT: content_type} try: raw_sqs = SearchQuerySet().filter(**query)[:1] wrapped_sqs = self.get_wrapped_search_results(raw_sqs) sqs = wrapped_sqs[0] except IndexError: raise Search404("Search result using query {q!r} does not exist".format( q=query)) more_like_this = () # the model may no longer be in the database, instead being only backed # by the search backend. model_instance = sqs.object.object if model_instance is not None: raw_mlt = SearchQuerySet().more_like_this(model_instance)[:5] more_like_this = self.get_wrapped_search_results(raw_mlt) form = PreSelectedModelSearchForm(request.GET or None, load_all=False) form_valid = form.is_valid() context = { 'original': sqs, 'title': _('View stored data for this %s') % force_text(sqs.verbose_name), 'app_label': self.model._meta.app_label, 'module_name': force_text(self.model._meta.verbose_name_plural), 'haystack_settings': self.get_settings(), 'has_change_permission': self.has_change_permission(request, sqs), 'similar_objects': more_like_this, 'haystack_version': _haystack_version, 'form': form, 'form_valid': form_valid, } return render_to_response('admin/haystackbrowser/view.html', context, context_instance=RequestContext(request))
def view(self, request, content_type, pk): """The view for showing the results of a single item in the Haystack index. :param request: the current request. :type request: WSGIRequest :param content_type: ``app_label`` and ``model_name`` as stored in Haystack, separated by "." :type content_type: string. :param pk: the object identifier stored in Haystack :type pk: string. :return: A template rendered into an HttpReponse """ if not self.has_change_permission(request, None): raise PermissionDenied("Not a superuser") query = {DJANGO_ID: pk, DJANGO_CT: content_type} try: raw_sqs = SearchQuerySet().filter(**query)[:1] wrapped_sqs = self.get_wrapped_search_results(raw_sqs) sqs = wrapped_sqs[0] except IndexError: raise Search404( "Search result using query {q!r} does not exist".format( q=query)) except SearchBackendError as e: raise Search404("{exc!r} while trying query {q!r}".format(q=query, exc=e)) more_like_this = () # the model may no longer be in the database, instead being only backed # by the search backend. model_instance = sqs.object.object if model_instance is not None: # Refs #GH-15 - elasticsearch-py 2.x does not implement a .mlt # method, but currently there's nothing in haystack-proper which # prevents using the 2.x series with the haystack-es1 backend. # At some point haystack will have a separate es backend ... # and I have no idea if/how I'm going to support that. try: raw_mlt = SearchQuerySet().more_like_this(model_instance)[:5] except AttributeError as e: logger.debug( "Support for 'more like this' functionality was " "not found, possibly because you're using " "the elasticsearch-py 2.x series with haystack's " "ES1.x backend", exc_info=1, extra={'request': request}) raw_mlt = () more_like_this = self.get_wrapped_search_results(raw_mlt) form = PreSelectedModelSearchForm(request.GET or None, load_all=False) form_valid = form.is_valid() context = { 'original': sqs, 'title': _('View stored data for this %s') % force_text(sqs.verbose_name), 'app_label': self.model._meta.app_label, 'module_name': force_text(self.model._meta.verbose_name_plural), 'haystack_settings': self.get_settings(), 'has_change_permission': self.has_change_permission(request, sqs), 'similar_objects': more_like_this, 'haystack_version': _haystack_version, 'form': form, 'form_valid': form_valid, } # Update the context with variables that should be available to every page context.update(self.each_context_compat(request)) return self.do_render(request=request, template_name='admin/haystackbrowser/view.html', context=context)
def index(self, request): """The view for showing all the results in the Haystack index. Emulates the standard Django ChangeList mostly. :param request: the current request. :type request: WSGIRequest :return: A template rendered into an HttpReponse """ if not self.has_change_permission(request, None): raise PermissionDenied("Not a superuser") page_var = self.get_paginator_var(request) form = PreSelectedModelSearchForm(request.GET or None, load_all=False) minimum_page = form.fields[page_var].min_value # Make sure there are some models indexed available_models = model_choices() if len(available_models) <= 0: raise Search404('No search indexes bound via Haystack') # We've not selected any models, so we're going to redirect and select # all of them. This will bite me in the ass if someone searches for a string # but no models, but I don't know WTF they'd expect to return, anyway. # Note that I'm only doing this to sidestep this issue: # https://gist.github.com/3766607 if 'models' not in request.GET.keys(): # TODO: make this betterererer. new_qs = ['&models=%s' % x[0] for x in available_models] # if we're in haystack2, we probably want to provide the 'default' # connection so that it behaves as if "initial" were in place. if form.has_multiple_connections(): new_qs.append('&connection=' + form.fields['connection'].initial) new_qs = ''.join(new_qs) existing_query = request.GET.copy() if page_var in existing_query: existing_query.pop(page_var) existing_query[page_var] = minimum_page location = '%(path)s?%(existing_qs)s%(new_qs)s' % { 'existing_qs': existing_query.urlencode(), 'new_qs': new_qs, 'path': request.path_info, } return HttpResponseRedirect(location) sqs = form.search() cleaned_GET = form.cleaned_data_querydict try: page_no = int(cleaned_GET.get(PAGE_VAR, minimum_page)) except ValueError: page_no = minimum_page results_per_page = self.get_results_per_page(request) paginator = Paginator(sqs, results_per_page) try: page = paginator.page(page_no + 1) except (InvalidPage, ValueError): # paginator.page may raise InvalidPage if we've gone too far # meanwhile, casting the querystring parameter may raise ValueError # if it's None, or '', or other silly input. raise Search404("Invalid page") query = request.GET.get(self.get_search_var(request), None) connection = request.GET.get('connection', None) title = self.model._meta.verbose_name_plural wrapped_facets = FacetWrapper( sqs.facet_counts(), querydict=form.cleaned_data_querydict.copy()) context = { 'results': self.get_wrapped_search_results(page.object_list), 'pagination_required': page.has_other_pages(), # this may be expanded into xrange(*page_range) to copy what # the paginator would yield. This prevents 50000+ pages making # the page slow to render because of django-debug-toolbar. 'page_range': (1, paginator.num_pages + 1), 'page_num': page.number, 'result_count': paginator.count, 'opts': self.model._meta, 'title': force_text(title), 'root_path': getattr(self.admin_site, 'root_path', None), 'app_label': self.model._meta.app_label, 'filtered': True, 'form': form, 'form_valid': form.is_valid(), 'query_string': self.get_current_query_string(request, remove=[page_var]), 'search_model_count': len(cleaned_GET.getlist('models')), 'search_facet_count': len(cleaned_GET.getlist('possible_facets')), 'search_var': self.get_search_var(request), 'page_var': page_var, 'facets': wrapped_facets, 'applied_facets': form.applied_facets(), 'module_name': force_text(self.model._meta.verbose_name_plural), 'cl': FakeChangeListForPaginator(request, page, results_per_page, self.model._meta), 'haystack_version': _haystack_version, # Note: the empty Media object isn't specficially required for the # standard Django admin, but is apparently a pre-requisite for # things like Grappelli. # See #1 (https://github.com/kezabelle/django-haystackbrowser/pull/1) 'media': Media() } # Update the context with variables that should be available to every page context.update(self.each_context_compat(request)) return self.do_render( request=request, template_name='admin/haystackbrowser/result_list.html', context=context)
def view(self, request, content_type, pk): """The view for showing the results of a single item in the Haystack index. :param request: the current request. :type request: WSGIRequest :param content_type: ``app_label`` and ``model_name`` as stored in Haystack, separated by "." :type content_type: string. :param pk: the object identifier stored in Haystack :type pk: string. :return: A template rendered into an HttpReponse """ if not self.has_change_permission(request, None): raise PermissionDenied("Not a superuser") query = {DJANGO_ID: pk, DJANGO_CT: content_type} try: raw_sqs = SearchQuerySet().filter(**query)[:1] wrapped_sqs = self.get_wrapped_search_results(raw_sqs) sqs = wrapped_sqs[0] except IndexError: raise Search404("Search result using query {q!r} does not exist".format( q=query)) except SearchBackendError as e: raise Search404("{exc!r} while trying query {q!r}".format( q=query, exc=e)) more_like_this = () # the model may no longer be in the database, instead being only backed # by the search backend. model_instance = sqs.object.object if model_instance is not None: # Refs #GH-15 - elasticsearch-py 2.x does not implement a .mlt # method, but currently there's nothing in haystack-proper which # prevents using the 2.x series with the haystack-es1 backend. # At some point haystack will have a separate es backend ... # and I have no idea if/how I'm going to support that. try: raw_mlt = SearchQuerySet().more_like_this(model_instance)[:5] except AttributeError as e: logger.debug("Support for 'more like this' functionality was " "not found, possibly because you're using " "the elasticsearch-py 2.x series with haystack's " "ES1.x backend", exc_info=1, extra={'request': request}) raw_mlt = () more_like_this = self.get_wrapped_search_results(raw_mlt) form = PreSelectedModelSearchForm(request.GET or None, load_all=False) form_valid = form.is_valid() context = { 'original': sqs, 'title': _('View stored data for this %s') % force_text(sqs.verbose_name), 'app_label': self.model._meta.app_label, 'module_name': force_text(self.model._meta.verbose_name_plural), 'haystack_settings': self.get_settings(), 'has_change_permission': self.has_change_permission(request, sqs), 'similar_objects': more_like_this, 'haystack_version': _haystack_version, 'form': form, 'form_valid': form_valid, } return self.do_render(request=request, template_name='admin/haystackbrowser/view.html', context=context)
def index(self, request): """The view for showing all the results in the Haystack index. Emulates the standard Django ChangeList mostly. :param request: the current request. :type request: WSGIRequest :return: A template rendered into an HttpReponse """ if not self.has_change_permission(request, None): raise PermissionDenied("Not a superuser") page_var = self.get_paginator_var(request) form = PreSelectedModelSearchForm(request.GET or None, load_all=False) minimum_page = form.fields[page_var].min_value # Make sure there are some models indexed available_models = model_choices() if len(available_models) <= 0: raise Search404('No search indexes bound via Haystack') # We've not selected any models, so we're going to redirect and select # all of them. This will bite me in the ass if someone searches for a string # but no models, but I don't know WTF they'd expect to return, anyway. # Note that I'm only doing this to sidestep this issue: # https://gist.github.com/3766607 if 'models' not in request.GET.keys(): # TODO: make this betterererer. new_qs = ['&models=%s' % x[0] for x in available_models] # if we're in haystack2, we probably want to provide the 'default' # connection so that it behaves as if "initial" were in place. if form.has_multiple_connections(): new_qs.append('&connection=' + form.fields['connection'].initial) new_qs = ''.join(new_qs) existing_query = request.GET.copy() if page_var in existing_query: existing_query.pop(page_var) existing_query[page_var] = minimum_page location = '%(path)s?%(existing_qs)s%(new_qs)s' % { 'existing_qs': existing_query.urlencode(), 'new_qs': new_qs, 'path': request.path_info, } return HttpResponseRedirect(location) sqs = form.search() cleaned_GET = form.cleaned_data_querydict try: page_no = int(cleaned_GET.get(PAGE_VAR, minimum_page)) except ValueError: page_no = minimum_page results_per_page = self.get_results_per_page(request) paginator = Paginator(sqs, results_per_page) try: page = paginator.page(page_no+1) except (InvalidPage, ValueError): # paginator.page may raise InvalidPage if we've gone too far # meanwhile, casting the querystring parameter may raise ValueError # if it's None, or '', or other silly input. raise Search404("Invalid page") query = request.GET.get(self.get_search_var(request), None) connection = request.GET.get('connection', None) title = self.model._meta.verbose_name_plural wrapped_facets = FacetWrapper( sqs.facet_counts(), querydict=form.cleaned_data_querydict.copy()) context = { 'results': self.get_wrapped_search_results(page.object_list), 'pagination_required': page.has_other_pages(), # this may be expanded into xrange(*page_range) to copy what # the paginator would yield. This prevents 50000+ pages making # the page slow to render because of django-debug-toolbar. 'page_range': (1, paginator.num_pages + 1), 'page_num': page.number, 'result_count': paginator.count, 'opts': self.model._meta, 'title': force_text(title), 'root_path': getattr(self.admin_site, 'root_path', None), 'app_label': self.model._meta.app_label, 'filtered': True, 'form': form, 'form_valid': form.is_valid(), 'query_string': self.get_current_query_string(request, remove=[page_var]), 'search_model_count': len(cleaned_GET.getlist('models')), 'search_facet_count': len(cleaned_GET.getlist('possible_facets')), 'search_var': self.get_search_var(request), 'page_var': page_var, 'facets': wrapped_facets, 'applied_facets': form.applied_facets(), 'module_name': force_text(self.model._meta.verbose_name_plural), 'cl': FakeChangeListForPaginator(request, page, results_per_page, self.model._meta), 'haystack_version': _haystack_version, # Note: the empty Media object isn't specficially required for the # standard Django admin, but is apparently a pre-requisite for # things like Grappelli. # See #1 (https://github.com/kezabelle/django-haystackbrowser/pull/1) 'media': Media() } return self.do_render(request=request, template_name='admin/haystackbrowser/result_list.html', context=context)