Last Updated: September 09, 2019
·
2.322K
· sputnikus

Generating SearchQuerySet with multiple boolean operators in Haystack

By default, Haystack provides you a few ways of making SearchQuerySet out of the query string. You can use basic filter() method, but it only supports one default boolean operator at the time. Or you can use raw_search(), which doesn't integrate well with other things (especially in ModelSearch). Or you can hardcode your query.

Or you can create your own form and put these two methods in it:

def search(self):
    if not self.is_valid():
        return self.no_query_found()

    if not self.cleaned_data.get('q'):
        return self.no_query_found()

    sqs = self._parse_query(self.cleaned_data['q'])

    if self.load_all:
        sqs = sqs.load_all()

    return sqs      

def _parse_query(self, query_content):
    words = iter(query_content.split())
    result_queryset = self.searchqueryset
    for word in words:
        try:
            if word == 'AND':
                result_queryset = result_queryset.filter_and(
                    content=words.next())
            elif word == 'OR':
                result_queryset = result_queryset.filter_or(
                    content=words.next())
            elif word == 'NOT':
                result_queryset = result_queryset.exclude(
                    content=words.next())
            else:
                result_queryset = result_queryset.filter(
                    content=word)
        except StopIteration:
            return result_queryset
    return result_queryset

2 Responses
Add your response

Thanks! You save my day!

over 1 year ago ·

Great solution @sputnikus. Thanks for sharing.

over 1 year ago ·