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
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
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")])))
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)
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") ])))
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")
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")])))
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")))
def test_with_phrase_unclosed(self): filters, query = parse_query_string('"hello world') self.assertDictEqual(filters, {}) self.assertEqual(repr(query), repr(Phrase("hello world")))
def test_simple_query(self): filters, query = parse_query_string('hello world') self.assertDictEqual(filters, {}) self.assertEqual(repr(query), repr(PlainText("hello world")))
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(), })