Guest User

Untitled

a guest
Jul 18th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.22 KB | None | 0 0
  1. from django.contrib.postgres.search import TrigramSimilarity
  2. from django.db.models import Case, When, Q, IntegerField
  3.  
  4. def filter_by_trigram_similarity(qs, field_name, search_term, similarity=0.15):
  5. if not search_term:
  6. return qs
  7.  
  8. similarity_name = field_name + '_similarity'
  9. strict_matching_name = field_name + '_strict_matching'
  10.  
  11. qs = qs.annotate(
  12. **{
  13. strict_matching_name: Case(
  14. When(**{field_name + '__iexact': search_term, 'then': 3}),
  15. When(**{field_name + '__istartswith': search_term, 'then': 2}),
  16. When(**{field_name + '__icontains': search_term, 'then': 1}),
  17. output_field=IntegerField(),
  18. default=0
  19. )
  20. }
  21. )
  22.  
  23. qs = qs.annotate(**{similarity_name: TrigramSimilarity(field_name, search_term)})
  24.  
  25. qs = qs.filter(
  26. Q(**{similarity_name + '__gt': similarity}) |
  27. # following line is required if column's max length is big,
  28. # because in this case similarity can be less
  29. # than minimum similarity, but strict match exists
  30. Q(**{strict_matching_name + '__gt': 0})
  31. )
  32.  
  33. return qs.order_by(
  34. '-' + strict_matching_name,
  35. '-' + similarity_name)
Add Comment
Please, Sign In to add comment