Ejemplo n.º 1
0
def page_filter_search(q, pages, all_pages=None, ordering=None):
    # Parse query
    filters, query = parse_query_string(q,
                                        operator="and",
                                        zero_terms=MATCH_ALL)

    # Live filter
    live_filter = filters.get("live") or filters.get("published")
    live_filter = live_filter and live_filter.lower()

    if live_filter in ["yes", "true"]:
        if all_pages is not None:
            all_pages = all_pages.filter(live=True)
        pages = pages.filter(live=True)
    elif live_filter in ["no", "false"]:
        if all_pages is not None:
            all_pages = all_pages.filter(live=False)
        pages = pages.filter(live=False)

    # Search
    if all_pages is not None:
        all_pages = all_pages.search(query, order_by_relevance=not ordering)
    pages = pages.search(query, order_by_relevance=not ordering)

    return pages, all_pages
Ejemplo n.º 2
0
def page_filter_search(q, pages, all_pages=None, ordering=None):
    # Parse query
    filters, query = parse_query_string(q,
                                        operator='and',
                                        zero_terms=MATCH_ALL)

    # Live filter
    live_filter = filters.get('live') or filters.get('published')
    live_filter = live_filter and live_filter.lower()

    if live_filter in ['yes', 'true']:
        if all_pages is not None:
            all_pages = all_pages.filter(live=True)
        pages = pages.filter(live=True)
    elif live_filter in ['no', 'false']:
        if all_pages is not None:
            all_pages = all_pages.filter(live=False)
        pages = pages.filter(live=False)

    # Search
    if all_pages is not None:
        all_pages = all_pages.search(query, order_by_relevance=not ordering)
    pages = pages.search(query, order_by_relevance=not ordering)

    return pages, all_pages
Ejemplo n.º 3
0
    def test_with_simple_and_phrase(self):
        filters, query = parse_query_string('this is simple "hello world"')

        self.assertDictEqual(filters, {})
        self.assertEqual(
            repr(query),
            repr(And([PlainText("this is simple"),
                      Phrase("hello world")])))
Ejemplo n.º 4
0
    def get_queryset(self):
        # get keyword query; support filters & phrase matching with double quotes
        # see https://docs.wagtail.io/en/stable/topics/search/searching.html#query-string-parsing
        q = self.request.GET.get("q", "")
        _filters, query = parse_query_string(q)  # not using these filters yet
        query.operator = "or"  # set query operator to OR (default is AND)

        # execute search; exclude unpublished pages.
        # NOTE results sorted by relevance by default; to override sort the QS
        # first and then pass order_by_relevance=false to .search()
        return self.model.objects.live().search(query)
Ejemplo n.º 5
0
    def test_operator(self):
        filters, query = parse_query_string('this is simple "hello world"',
                                            operator='or')

        self.assertDictEqual(filters, {})
        self.assertEqual(
            repr(query),
            repr(
                Or([
                    PlainText("this is simple", operator='or'),
                    Phrase("hello world")
                ])))
Ejemplo n.º 6
0
 def get(self, request, *args, **kwargs):
     query_string = request.GET.get('q')
     if query_string is None:
         return HttpResponseBadRequest()
     filters, query = parse_query_string(query_string)
     type = filters.get('type')
     if type not in ['pages', 'images', 'documents', 'tags']:
         return HttpResponseBadRequest()
     t0 = time.time()
     if type == 'pages':
         pages = self.get_pages_queryset().specific().search(query)
         pages = self.paginate_queryset(pages)
         ser = BanneredChildrenSerializer()
         ser._context = self.get_serializer_context()
         result = {
             'pages': ser.to_representation(pages),
             'time': self.measure(t0)
         }
     if type == 'images':
         images = self.get_image_queryset().values('id').search(query)
         images = self.paginate_queryset(images)
         result = {
             'images':
             GalleryImageSerializer(many=True).to_representation(images),
             'time':
             self.measure(t0)
         }
     if type == 'documents':
         documents = []
         result = {'documents': documents, 'time': self.measure(t0)}
     if type == 'tags':
         tags = set(query.query_string.split(' '))
         pages = Page.objects.live().public().filter(
             id__in=PageTag.objects.filter(tag__name__in=tags).values_list(
                 'content_object')).specific()
         pages = self.paginate_queryset(pages)
         ser = BanneredChildrenSerializer()
         ser._context = self.get_serializer_context()
         result = {
             'tags': ser.to_representation(pages),
             'time': self.measure(t0)
         }
     return HttpResponse(json.dumps(result),
                         content_type="application/json")
Ejemplo n.º 7
0
    def test_multiple_phrases(self):
        filters, query = parse_query_string('"hello world" "hi earth"')

        self.assertEqual(
            repr(query), repr(And([Phrase("hello world"),
                                   Phrase("hi earth")])))
Ejemplo n.º 8
0
    def test_phrase_with_filter(self):
        filters, query = parse_query_string(
            '"hello world" author:"foo bar" bar:beer')

        self.assertDictEqual(filters, {'author': 'foo bar', 'bar': 'beer'})
        self.assertEqual(repr(query), repr(Phrase("hello world")))
Ejemplo n.º 9
0
    def test_with_phrase_unclosed(self):
        filters, query = parse_query_string('"hello world')

        self.assertDictEqual(filters, {})
        self.assertEqual(repr(query), repr(Phrase("hello world")))
Ejemplo n.º 10
0
    def test_simple_query(self):
        filters, query = parse_query_string('hello world')

        self.assertDictEqual(filters, {})
        self.assertEqual(repr(query), repr(PlainText("hello world")))
Ejemplo n.º 11
0
def search(request):
    pages = all_pages = Page.objects.all().prefetch_related(
        'content_type').specific()
    q = MATCH_ALL
    content_types = []
    pagination_query_params = QueryDict({}, mutable=True)
    ordering = None

    if 'ordering' in request.GET:
        if request.GET['ordering'] in [
                'title', '-title', 'latest_revision_created_at',
                '-latest_revision_created_at', 'live', '-live'
        ]:
            ordering = request.GET['ordering']

            if ordering == 'title':
                pages = pages.order_by('title')
            elif ordering == '-title':
                pages = pages.order_by('-title')

            if ordering == 'latest_revision_created_at':
                pages = pages.order_by('latest_revision_created_at')
            elif ordering == '-latest_revision_created_at':
                pages = pages.order_by('-latest_revision_created_at')

            if ordering == 'live':
                pages = pages.order_by('live')
            elif ordering == '-live':
                pages = pages.order_by('-live')

    if 'content_type' in request.GET:
        pagination_query_params['content_type'] = request.GET['content_type']

        app_label, model_name = request.GET['content_type'].split('.')

        try:
            selected_content_type = ContentType.objects.get_by_natural_key(
                app_label, model_name)
        except ContentType.DoesNotExist:
            raise Http404

        pages = pages.filter(content_type=selected_content_type)
    else:
        selected_content_type = None

    if 'q' in request.GET:
        form = SearchForm(request.GET)
        if form.is_valid():
            q = form.cleaned_data['q']
            pagination_query_params['q'] = q

            # Parse query
            filters, query = parse_query_string(q,
                                                operator='and',
                                                zero_terms=MATCH_ALL)

            # Live filter
            live_filter = filters.get('live') or filters.get('published')
            live_filter = live_filter and live_filter.lower()
            if live_filter in ['yes', 'true']:
                all_pages = all_pages.filter(live=True)
                pages = pages.filter(live=True)
            elif live_filter in ['no', 'false']:
                all_pages = all_pages.filter(live=False)
                pages = pages.filter(live=False)

            # Search
            all_pages = all_pages.search(query,
                                         order_by_relevance=not ordering)
            pages = pages.search(query, order_by_relevance=not ordering)

            # Facets
            if pages.supports_facet:
                content_types = [(ContentType.objects.get(id=content_type_id),
                                  count) for content_type_id, count in
                                 all_pages.facet('content_type_id').items()]

    else:
        form = SearchForm()

    paginator = Paginator(pages, per_page=20)
    pages = paginator.get_page(request.GET.get('p'))

    if request.is_ajax():
        return TemplateResponse(
            request, "wagtailadmin/pages/search_results.html", {
                'pages': pages,
                'all_pages': all_pages,
                'query_string': q,
                'content_types': content_types,
                'selected_content_type': selected_content_type,
                'ordering': ordering,
                'pagination_query_params': pagination_query_params.urlencode(),
            })
    else:
        return TemplateResponse(
            request, "wagtailadmin/pages/search.html", {
                'search_form': form,
                'pages': pages,
                'all_pages': all_pages,
                'query_string': q,
                'content_types': content_types,
                'selected_content_type': selected_content_type,
                'ordering': ordering,
                'pagination_query_params': pagination_query_params.urlencode(),
            })