def test_configure_faceting_version2_has_data(unified_index):
    # mock out enough of the backend to get data
    indexed_models = Mock(return_value=[Model, Model])
    facet_fieldnames = Mock(_facet_fieldnames={'a': 1, 'b': 2})
    facet_fieldnames.attach_mock(indexed_models, 'get_indexed_models')
    unified_index.return_value = facet_fieldnames
    form = PreSelectedModelSearchForm(data={})
    assert form.configure_faceting() == [('a', 'A'), ('b', 'B')]
def test_configure_faceting_version2_has_data(unified_index):
    # mock out enough of the backend to get data
    indexed_models = Mock(return_value=[Model, Model])
    facet_fieldnames = Mock(_facet_fieldnames={'a': 1, 'b':2})
    facet_fieldnames.attach_mock(indexed_models, 'get_indexed_models')
    unified_index.return_value = facet_fieldnames
    form = PreSelectedModelSearchForm(data={})
    assert form.configure_faceting() == [('a', 'A'), ('b', 'B')]
def test_should_allow_faceting_version2_ok_backend():
    form = PreSelectedModelSearchForm(data={})
    NEW_CONFIG = {
        'default': {
            'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
            'PATH': 'test',
        }
    }
    with override_settings(HAYSTACK_CONNECTIONS=NEW_CONFIG):
        assert form.should_allow_faceting() is True
def test_should_allow_faceting_version2_ok_backend():
    form = PreSelectedModelSearchForm(data={})
    NEW_CONFIG = {
        'default': {
            'ENGINE':
            'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
            'PATH': 'test',
        }
    }
    with override_settings(HAYSTACK_CONNECTIONS=NEW_CONFIG):
        assert form.should_allow_faceting() is True
def test_configure_faceting_version1_has_data(field_mapping):
    field_mapping.return_value = {
        'a': {
            'facet_fieldname': 'A'
        },
        'b': {
            'facet_fieldname': 'B'
        }
    }
    form = PreSelectedModelSearchForm(data={})
    assert form.configure_faceting() == [('A', 'A'), ('B', 'B')]
def test_get_possible_connections_version2():
    form = PreSelectedModelSearchForm(data={})
    setting = {
        'default': {
            'TITLE': 'lol',
        },
        'other': {},
    }
    with override_settings(HAYSTACK_CONNECTIONS=setting):
        assert sorted(form.get_possible_connections()) == [
            ('default', 'lol'),
            ('other', 'other'),
        ]
def test_get_possible_connections_version2():
    form = PreSelectedModelSearchForm(data={})
    setting = {
        'default': {
            'TITLE': 'lol',
        },
        'other': {},
    }
    with override_settings(HAYSTACK_CONNECTIONS=setting):
        assert sorted(form.get_possible_connections()) == [
            ('default', 'lol'),
            ('other', 'other'),
        ]
Esempio n. 8
0
    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 test_has_multiple_connections_version2_nope():
    form = PreSelectedModelSearchForm(data={})
    with override_settings(HAYSTACK_CONNECTIONS={'default': 1}):
        assert form.has_multiple_connections() is False
Esempio n. 10
0
def test_configure_faceting_version2_without_data():
    form = PreSelectedModelSearchForm(data={})
    assert form.configure_faceting() == []
def test_should_allow_faceting_version1_ok_backend():
    form = PreSelectedModelSearchForm(data={})
    with override_settings(HAYSTACK_SEARCH_ENGINE='solr'):
        assert form.should_allow_faceting() is True
Esempio n. 12
0
def test_should_allow_faceting_version2_bad_backend():
    form = PreSelectedModelSearchForm(data={})
    # whoosh isn't supported for faceting
    assert form.should_allow_faceting() is False
Esempio n. 13
0
def test_should_allow_faceting_version1_ok_backend():
    form = PreSelectedModelSearchForm(data={})
    with override_settings(HAYSTACK_SEARCH_ENGINE='solr'):
        assert form.should_allow_faceting() is True
Esempio n. 14
0
def test_should_allow_faceting_version1_ok_backend():
    form = PreSelectedModelSearchForm(data={})
    assert form.should_allow_faceting() is False
def test_configure_faceting_version1_without_data(field_mapping):
    field_mapping.return_value = {}
    form = PreSelectedModelSearchForm(data={})
    assert form.configure_faceting() == []
def test_should_allow_faceting_version1_ok_backend():
    form = PreSelectedModelSearchForm(data={})
    assert form.should_allow_faceting() is False
Esempio n. 17
0
    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
        """
        page_var = self.get_paginator_var(request)
        form = PreSelectedModelSearchForm(request.GET or None, load_all=False)

        # Make sure there are some models indexed
        available_models = model_choices()
        if len(available_models) < 0:
            raise Http404

        # 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)
            qs = self.get_current_query_string(request, remove=['p'])
            return HttpResponseRedirect(request.path_info + qs + new_qs)

        try:
            sqs = form.search()
            try:
                page_no = int(request.GET.get(PAGE_VAR, 0))
            except ValueError:
                page_no = 0
            #page_no = int(request.GET.get(page_var, 1))
            results_per_page = self.get_results_per_page(request)
            paginator = Paginator(sqs, results_per_page)
            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 Http404

        query = request.GET.get(self.get_search_var(request), None)
        connection = request.GET.get('connection', None)
        title = self.model._meta.verbose_name_plural
        if query:
            title = string_concat(self.model._meta.verbose_name_plural,
                                  ' for "', query, '"')
        if connection:
            title = string_concat(title, ' using "', connection,
                                  '" connection')
        context = {
            'results':
            self.get_wrapped_search_results(page.object_list),
            'pagination_required':
            page.has_other_pages(),
            'page_range':
            paginator.page_range,
            'page_num':
            page.number,
            'result_count':
            paginator.count,
            'opts':
            self.model._meta,
            'title':
            force_unicode(title),
            'root_path':
            getattr(self.admin_site, 'root_path', None),
            'app_label':
            self.model._meta.app_label,
            'filtered':
            True,
            'form':
            form,
            'query_string':
            self.get_current_query_string(request, remove=['p']),
            'search_model_count':
            len(request.GET.getlist('models')),
            'search_facet_count':
            len(request.GET.getlist('possible_facets')),
            'search_var':
            self.get_search_var(request),
            'page_var':
            page_var,
            'facets':
            FacetWrapper(sqs.facet_counts()),
            'module_name':
            force_unicode(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 render_to_response('admin/haystackbrowser/result_list.html',
                                  context,
                                  context_instance=RequestContext(request))
Esempio n. 18
0
    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)
Esempio n. 19
0
    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)
def test_configure_faceting_version1_has_data(field_mapping):
    field_mapping.return_value = {'a': {'facet_fieldname': 'A'},
                                  'b': {'facet_fieldname': 'B'}}
    form = PreSelectedModelSearchForm(data={})
    assert form.configure_faceting() == [('A', 'A'), ('B', 'B')]
def test_configure_faceting_version2_without_data():
    form = PreSelectedModelSearchForm(data={})
    assert form.configure_faceting() == []
def test_has_multiple_connections_version1():
    form = PreSelectedModelSearchForm(data={})
    assert form.has_multiple_connections() is False
Esempio n. 23
0
def test_guess_haystack_version2():
    form = PreSelectedModelSearchForm(data={})
    assert form.version == 2
Esempio n. 24
0
def test_configure_faceting_version1_without_data(field_mapping):
    field_mapping.return_value = {}
    form = PreSelectedModelSearchForm(data={})
    assert form.configure_faceting() == []
def test_should_allow_faceting_version2_bad_backend():
    form = PreSelectedModelSearchForm(data={})
    # whoosh isn't supported for faceting
    assert form.should_allow_faceting() is False
Esempio n. 26
0
    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)
Esempio n. 27
0
def test_has_multiple_connections_version1():
    form = PreSelectedModelSearchForm(data={})
    assert form.has_multiple_connections() is False
Esempio n. 28
0
    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)
Esempio n. 29
0
def test_has_multiple_connections_version2_nope():
    form = PreSelectedModelSearchForm(data={})
    with override_settings(HAYSTACK_CONNECTIONS={'default': 1}):
        assert form.has_multiple_connections() is False
    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
        """
        page_var = self.get_paginator_var(request)
        form = PreSelectedModelSearchForm(request.GET or None, load_all=False)

        # Make sure there are some models indexed
        available_models = model_choices()
        if len(available_models) < 0:
            raise Http404

        # 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)
            qs = self.get_current_query_string(request, remove=['p'])
            return HttpResponseRedirect(request.path_info + qs + new_qs)

        try:
            sqs = form.search()
            try:
                page_no = int(request.GET.get(PAGE_VAR, 0))
            except ValueError:
                page_no = 0
            #page_no = int(request.GET.get(page_var, 1))
            results_per_page = self.get_results_per_page(request)
            paginator = Paginator(sqs, results_per_page)
            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 Http404

        query = request.GET.get(self.get_search_var(request), None)
        connection = request.GET.get('connection', None)
        title = self.model._meta.verbose_name_plural
        if query:
            title = string_concat(self.model._meta.verbose_name_plural, ' for "',
                                  query, '"')
        if connection:
            title = string_concat(title, ' using "', connection, '" connection')
        context = {
            'results': self.get_wrapped_search_results(page.object_list),
            'pagination_required': page.has_other_pages(),
            'page_range': paginator.page_range,
            'page_num': page.number,
            'result_count': paginator.count,
            'opts': self.model._meta,
            'title': force_unicode(title),
            'root_path': getattr(self.admin_site, 'root_path', None),
            'app_label': self.model._meta.app_label,
            'filtered': True,
            'form': form,
            'query_string': self.get_current_query_string(request, remove=['p']),
            'search_model_count': len(request.GET.getlist('models')),
            'search_facet_count': len(request.GET.getlist('possible_facets')),
            'search_var': self.get_search_var(request),
            'page_var': page_var,
            'facets': FacetWrapper(sqs.facet_counts()),
            'module_name': force_unicode(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 render_to_response('admin/haystackbrowser/result_list.html', context,
                                  context_instance=RequestContext(request))
Esempio n. 31
0
    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
        """
        page_var = self.get_paginator_var(request)
        form = PreSelectedModelSearchForm(request.GET or None, load_all=False)

        # 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)
            qs = self.get_current_query_string(request, remove=["p"])
            return HttpResponseRedirect(request.path_info + qs + new_qs)

        try:
            sqs = form.search()
            try:
                page_no = int(request.GET.get(PAGE_VAR, 0))
            except ValueError:
                page_no = 0
            # page_no = int(request.GET.get(page_var, 1))
            results_per_page = self.get_results_per_page(request)
            paginator = Paginator(sqs, results_per_page)
            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
        if query:
            title = string_concat(self.model._meta.verbose_name_plural, ' for "', query, '"')
        if connection:
            title = string_concat(title, ' using "', connection, '" connection')
        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,
            "query_string": self.get_current_query_string(request, remove=["p"]),
            "search_model_count": len(request.GET.getlist("models")),
            "search_facet_count": len(request.GET.getlist("possible_facets")),
            "search_var": self.get_search_var(request),
            "page_var": page_var,
            "facets": FacetWrapper(sqs.facet_counts()),
            "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 render_to_response(
            "admin/haystackbrowser/result_list.html", context, context_instance=RequestContext(request)
        )