modified search filter for backoffice account view

This commit is contained in:
Anatoly 2020-01-23 17:31:37 +03:00
parent 7391463f5a
commit 6b819e2ed4
2 changed files with 52 additions and 18 deletions

View File

@ -33,14 +33,8 @@ class AccountBackOfficeFilter(filters.FilterSet):
return queryset
def search_text(self, queryset, name, value):
queryset = queryset.annotate_vector()
if value not in EMPTY_VALUES:
# search by exact value
filtered_qs = queryset.filter(vector=value)
if not filtered_qs.exists():
# if filtered qs is None find something
filtered_qs = queryset.filter(vector__icontains=value)
return filtered_qs
return queryset.full_text_search(value)
return queryset
def by_role_country_code(self, queryset, name, value):

View File

@ -1,6 +1,6 @@
"""Account models"""
from datetime import datetime
from django.contrib.postgres.search import TrigramSimilarity
from django.conf import settings
from django.contrib.auth.models import AbstractUser, UserManager as BaseUserManager
from django.core.mail import send_mail
@ -21,7 +21,6 @@ from main.models import SiteSettings
from utils.models import GMTokenGenerator
from utils.models import ImageMixin, ProjectBaseMixin, PlatformMixin
from utils.tokens import GMRefreshToken
from django.contrib.postgres.search import SearchVector
from phonenumber_field.modelfields import PhoneNumberField
@ -146,15 +145,56 @@ class UserQuerySet(models.QuerySet):
role = Role.objects.filter(role=Role.ESTABLISHMENT_MANAGER).first()
return self.by_role(role).filter(userrole__establishment=establishment)
def annotate_vector(self):
"""Full-text search"""
return self.annotate(vector=SearchVector(
'username',
'first_name',
'last_name',
'email',
'phone',
))
def full_text_search(self, search_value: str):
return self.annotate(
username_similarity=models.Case(
models.When(
models.Q(username__isnull=False),
then=TrigramSimilarity('username', search_value.lower())
),
default=0,
output_field=models.FloatField()
),
first_name_similarity=models.Case(
models.When(
models.Q(first_name__isnull=False),
then=TrigramSimilarity('first_name', search_value.lower())
),
default=0,
output_field=models.FloatField()
),
last_name_similarity=models.Case(
models.When(
models.Q(last_name__isnull=False),
then=TrigramSimilarity('last_name', search_value.lower())
),
default=0,
output_field=models.FloatField()
),
email_similarity=models.Case(
models.When(
models.Q(email__isnull=False),
then=TrigramSimilarity('email', search_value.lower())
),
default=0,
output_field=models.FloatField()
),
phone_similarity=models.Case(
models.When(
models.Q(phone__isnull=False),
then=TrigramSimilarity('phone', search_value.lower())
),
default=0,
output_field=models.FloatField()
),
relevance=(
models.F('username_similarity') +
models.F('first_name_similarity') +
models.F('last_name_similarity') +
models.F('email_similarity') +
models.F('phone_similarity')
),
).filter(relevance__gte=0.1).order_by('-relevance')
def by_role_country_code(self, country_code: str):
"""Filter by role country code."""