Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from django.contrib.postgres.search import TrigramSimilarity
- from django.db.models import Case, When, Q, IntegerField
- def filter_by_trigram_similarity(qs, field_name, search_term, similarity=0.15):
- if not search_term:
- return qs
- similarity_name = field_name + '_similarity'
- strict_matching_name = field_name + '_strict_matching'
- qs = qs.annotate(
- **{
- strict_matching_name: Case(
- When(**{field_name + '__iexact': search_term, 'then': 3}),
- When(**{field_name + '__istartswith': search_term, 'then': 2}),
- When(**{field_name + '__icontains': search_term, 'then': 1}),
- output_field=IntegerField(),
- default=0
- )
- }
- )
- qs = qs.annotate(**{similarity_name: TrigramSimilarity(field_name, search_term)})
- qs = qs.filter(
- Q(**{similarity_name + '__gt': similarity}) |
- # following line is required if column's max length is big,
- # because in this case similarity can be less
- # than minimum similarity, but strict match exists
- Q(**{strict_matching_name + '__gt': 0})
- )
- return qs.order_by(
- '-' + strict_matching_name,
- '-' + similarity_name)
Add Comment
Please, Sign In to add comment