Nicer search, minor fixes.
[wolnelektury.git] / src / search / utils.py
1 from django.conf import settings
2 from django.db.models import Func
3 from django.contrib.postgres.search import SearchQuery, SearchVectorField
4
5
6 class UnaccentSearchQuery(SearchQuery):
7     '''
8     The idea is to run unaccent *after* the query is already passed through the language dictionary.
9     '''
10     def as_sql(self, *args, **kwargs):
11         sql, params = super().as_sql(*args, **kwargs)
12         if settings.SEARCH_USE_UNACCENT:
13             sql = f'unaccent({sql}::text)::tsquery'
14         return sql, params
15
16
17 class UnaccentSearchVector(Func):
18     '''
19     We do the indexing twice, to account for non-diacritic versions.
20     For example: user enters 'róże' -> stem to 'róża' -> unaccent to 'roza'.
21     But user enters 'roze' -> stem leaves it as is, so we need original form in the vector.
22     '''
23     function='to_tsvector'
24     if settings.SEARCH_USE_UNACCENT:
25         template = f'''unaccent(
26         %(function)s('{settings.SEARCH_CONFIG}', %(expressions)s)::text)::tsvector ||
27         to_tsvector(
28         '{settings.SEARCH_CONFIG_SIMPLE}', 
29         unaccent(%(expressions)s)
30         )'''
31     output_field = SearchVectorField()