Postgres-backed partial search functionality in Wagtail


Solution 1:

The Wagtail search API is being reconstructed to ensure that autocomplete functions consistently across all backends.

At present, the search data can be accessed through the


model. However, there is no built-in capability for an autocomplete query in

, so we need to perform this task manually. Here are the steps to follow for achieving this.

from import SearchQuery
from wagtail.contrib.postgres_search.models import IndexEntry
class SearchAutocomplete(SearchQuery):
    def as_sql(self, compiler, connection):
        return "to_tsquery(''%s':*')", [self.value]
query = SearchAutocomplete('postg')
# All results containing words starting with “postg”
# should be displayed, sorted by relevance.

Solution 2:

Although it lacks documentation, the essence of utilizing a request object for autocomplete filtering with Postgres seems to be present.

from django.conf import settings
from import get_search_backend
from import FilterFieldError, OrderByFieldError
def filter_queryset(queryset, request):
    search_query = request.GET.get("search", "").strip()
    search_enabled = getattr(settings, 'WAGTAILAPI_SEARCH_ENABLED', True)
    if 'search' in request.GET and search_query:
        if not search_enabled:
            raise BadRequestError("search is disabled")
        search_operator = request.GET.get('search_operator', None)
        order_by_relevance = 'order' not in request.GET
        sb = get_search_backend()
            queryset = sb.autocomplete(search_query, queryset, operator=search_operator, order_by_relevance=order_by_relevance)
        except FilterFieldError as e:
            raise BadRequestError("cannot filter by '{}' while searching (field is not indexed)".format(e.field_name))
        except OrderByFieldError as e:
            raise BadRequestError("cannot order by '{}' while searching (field is not indexed)".format(e.field_name))

The significant instruction is to make use of the code labeled as



In order to utilize custom fields with autocomplete, it is necessary to include them in


as both an




. This can be illustrated with an example.

search_fields = Page.search_fields + [
    index.SearchField("field_to_index", partial_match=True)
    index.AutocompleteField("field_to_index", partial_match=True),

If you are using Wagtail 2.3, this solution will work. However, it is not guaranteed to work with older versions and there is no guarantee that it will be included in future official documents. Previous documents stated that autocomplete with Postgres was impossible, but thanks to the efforts of Bertrand Bordage, this has been proven untrue.

Frequently Asked Questions