employees trigram search for back-office
This commit is contained in:
parent
7a7d7a70b0
commit
4b45cab976
|
|
@ -1,6 +1,8 @@
|
||||||
"""Establishment app filters."""
|
"""Establishment app filters."""
|
||||||
from django.core.validators import EMPTY_VALUES
|
from django.core.validators import EMPTY_VALUES
|
||||||
from django_filters import rest_framework as filters
|
from django_filters import rest_framework as filters
|
||||||
|
from rest_framework.serializers import ValidationError
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from establishment import models
|
from establishment import models
|
||||||
|
|
||||||
|
|
@ -79,3 +81,12 @@ class EmployeeBackFilter(filters.FilterSet):
|
||||||
if value not in EMPTY_VALUES:
|
if value not in EMPTY_VALUES:
|
||||||
return queryset.search_by_name_or_last_name(value)
|
return queryset.search_by_name_or_last_name(value)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
|
class EmployeeBackSearchFilter(EmployeeBackFilter):
|
||||||
|
def search_by_name_or_last_name(self, queryset, name, value):
|
||||||
|
if value not in EMPTY_VALUES:
|
||||||
|
if len(value) < 3:
|
||||||
|
raise ValidationError({'detail': _('Type at least 3 characters to search please.')})
|
||||||
|
return queryset.trigram_search(value)
|
||||||
|
return queryset
|
||||||
|
|
|
||||||
16
apps/establishment/migrations/0072_auto_20200115_1702.py
Normal file
16
apps/establishment/migrations/0072_auto_20200115_1702.py
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Generated by Django 2.2.7 on 2020-01-15 17:02
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
from django.contrib.postgres.operations import TrigramExtension, BtreeGinExtension
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0071_auto_20200110_1055'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
TrigramExtension(),
|
||||||
|
BtreeGinExtension(),
|
||||||
|
]
|
||||||
22
apps/establishment/migrations/0073_auto_20200115_1710.py
Normal file
22
apps/establishment/migrations/0073_auto_20200115_1710.py
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Generated by Django 2.2.7 on 2020-01-15 17:10
|
||||||
|
|
||||||
|
import django.contrib.postgres.indexes
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('establishment', '0072_auto_20200115_1702'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddIndex(
|
||||||
|
model_name='employee',
|
||||||
|
index=django.contrib.postgres.indexes.GinIndex(fields=['name'], name='establishme_name_39fda6_gin'),
|
||||||
|
),
|
||||||
|
migrations.AddIndex(
|
||||||
|
model_name='employee',
|
||||||
|
index=django.contrib.postgres.indexes.GinIndex(fields=['last_name'], name='establishme_last_na_3c53de_gin'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -11,6 +11,8 @@ from django.contrib.gis.db.models.functions import Distance
|
||||||
from django.contrib.gis.geos import Point
|
from django.contrib.gis.geos import Point
|
||||||
from django.contrib.gis.measure import Distance as DistanceMeasure
|
from django.contrib.gis.measure import Distance as DistanceMeasure
|
||||||
from django.contrib.postgres.fields import ArrayField
|
from django.contrib.postgres.fields import ArrayField
|
||||||
|
from django.contrib.postgres.search import TrigramDistance
|
||||||
|
from django.contrib.postgres.indexes import GinIndex
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.core.validators import MinValueValidator, MaxValueValidator
|
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
@ -977,6 +979,13 @@ class EmployeeQuerySet(models.QuerySet):
|
||||||
]
|
]
|
||||||
return self.filter(reduce(lambda x, y: x | y, [models.Q(**i) for i in filters]))
|
return self.filter(reduce(lambda x, y: x | y, [models.Q(**i) for i in filters]))
|
||||||
|
|
||||||
|
def trigram_search(self, search_value: str):
|
||||||
|
"""Search with mistakes by name or last name."""
|
||||||
|
return self.annotate(
|
||||||
|
name_distance=TrigramDistance('name', search_value.lower()),
|
||||||
|
last_name_distance=TrigramDistance('last_name', search_value.lower()),
|
||||||
|
).filter(Q(name_distance__lte=0.7) | Q(last_name_distance__lte=0.7)).order_by('name_distance')
|
||||||
|
|
||||||
def search_by_name_or_last_name(self, value):
|
def search_by_name_or_last_name(self, value):
|
||||||
"""Search by name or last_name."""
|
"""Search by name or last_name."""
|
||||||
return self._generic_search(value, ['name', 'last_name'])
|
return self._generic_search(value, ['name', 'last_name'])
|
||||||
|
|
@ -987,6 +996,9 @@ class EmployeeQuerySet(models.QuerySet):
|
||||||
queryset=EstablishmentEmployee.objects.actual()
|
queryset=EstablishmentEmployee.objects.actual()
|
||||||
)).all().distinct()
|
)).all().distinct()
|
||||||
|
|
||||||
|
def with_extended_related(self):
|
||||||
|
return self.prefetch_related('establishments')
|
||||||
|
|
||||||
|
|
||||||
class Employee(BaseAttributes):
|
class Employee(BaseAttributes):
|
||||||
"""Employee model."""
|
"""Employee model."""
|
||||||
|
|
@ -1030,6 +1042,10 @@ class Employee(BaseAttributes):
|
||||||
|
|
||||||
verbose_name = _('Employee')
|
verbose_name = _('Employee')
|
||||||
verbose_name_plural = _('Employees')
|
verbose_name_plural = _('Employees')
|
||||||
|
indexes = [
|
||||||
|
GinIndex(fields=('name',)),
|
||||||
|
GinIndex(fields=('last_name',))
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentScheduleQuerySet(models.QuerySet):
|
class EstablishmentScheduleQuerySet(models.QuerySet):
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ urlpatterns = [
|
||||||
path('<int:establishment_id>/employees/', views.EstablishmentEmployeeListView.as_view(),
|
path('<int:establishment_id>/employees/', views.EstablishmentEmployeeListView.as_view(),
|
||||||
name='establishment-employees'),
|
name='establishment-employees'),
|
||||||
path('employees/', views.EmployeeListCreateView.as_view(), name='employees'),
|
path('employees/', views.EmployeeListCreateView.as_view(), name='employees'),
|
||||||
|
path('employees/search/', views.EmployeesListSearchViews.as_view(), name='employees-search'),
|
||||||
path('employees/<int:pk>/', views.EmployeeRUDView.as_view(), name='employees-rud'),
|
path('employees/<int:pk>/', views.EmployeeRUDView.as_view(), name='employees-rud'),
|
||||||
path('<int:establishment_id>/employee/<int:employee_id>/position/<int:position_id>',
|
path('<int:establishment_id>/employee/<int:employee_id>/position/<int:position_id>',
|
||||||
views.EstablishmentEmployeeCreateView.as_view(),
|
views.EstablishmentEmployeeCreateView.as_view(),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
from django.http import Http404, HttpResponse
|
from django.http import Http404, HttpResponse
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django_filters.rest_framework import DjangoFilterBackend
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
from rest_framework import generics, permissions, status
|
from rest_framework import generics, permissions, status, filters as rest_filters
|
||||||
|
|
||||||
from account.models import User
|
from account.models import User
|
||||||
from establishment import filters, models, serializers
|
from establishment import filters, models, serializers
|
||||||
|
|
@ -174,6 +174,15 @@ class EmployeeListCreateView(generics.ListCreateAPIView):
|
||||||
queryset = models.Employee.objects.all()
|
queryset = models.Employee.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
class EmployeesListSearchViews(generics.ListAPIView):
|
||||||
|
"""Employee search view"""
|
||||||
|
pagination_class = None
|
||||||
|
permission_classes = (permissions.AllowAny,)
|
||||||
|
queryset = models.Employee.objects.all()
|
||||||
|
filter_class = filters.EmployeeBackSearchFilter
|
||||||
|
serializer_class = serializers.EmployeeBackSerializers
|
||||||
|
|
||||||
|
|
||||||
class EstablishmentEmployeeListView(generics.ListCreateAPIView):
|
class EstablishmentEmployeeListView(generics.ListCreateAPIView):
|
||||||
"""Establishment emplyoees list view."""
|
"""Establishment emplyoees list view."""
|
||||||
permission_classes = (permissions.AllowAny,)
|
permission_classes = (permissions.AllowAny,)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user