Add member search api route

This commit is contained in:
Tanner Collin 2020-01-11 00:47:13 +00:00
parent fddaf083b4
commit 402ec28ff5
6 changed files with 76 additions and 0 deletions

View File

@ -12,7 +12,9 @@ class Member(models.Model):
set_details = models.BooleanField(default=False) set_details = models.BooleanField(default=False)
preferred_name = models.CharField(max_length=32, blank=True) preferred_name = models.CharField(max_length=32, blank=True)
status = models.CharField(max_length=32, blank=True)
phone = models.CharField(max_length=32, blank=True) phone = models.CharField(max_length=32, blank=True)
expire_date = models.DateField(default=date.today, blank=True, null=True)
current_start_date = models.DateField(default=date.today, blank=True, null=True) current_start_date = models.DateField(default=date.today, blank=True, null=True)
application_date = models.DateField(default=date.today, blank=True, null=True) application_date = models.DateField(default=date.today, blank=True, null=True)
vetted_date = models.DateField(blank=True, null=True) vetted_date = models.DateField(blank=True, null=True)

View File

@ -22,12 +22,20 @@ class UserSerializer(serializers.ModelSerializer):
depth = 1 depth = 1
# member viewing member list or other member
class OtherMemberSerializer(serializers.ModelSerializer):
class Meta:
model = models.Member
fields = ['preferred_name', 'last_name', 'status', 'current_start_date']
# member viewing himself
class MemberSerializer(serializers.ModelSerializer): class MemberSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.Member model = models.Member
fields = '__all__' fields = '__all__'
read_only_fields = ['user', 'application_date', 'current_start_date', 'vetted_date', 'monthly_fees', 'old_member_id'] read_only_fields = ['user', 'application_date', 'current_start_date', 'vetted_date', 'monthly_fees', 'old_member_id']
# adming viewing member
class AdminMemberSerializer(serializers.ModelSerializer): class AdminMemberSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = models.Member model = models.Member

View File

@ -3,6 +3,8 @@ from django.db.models import Max
from rest_framework import viewsets, views, permissions from rest_framework import viewsets, views, permissions
from rest_framework.response import Response from rest_framework.response import Response
from rest_auth.registration.views import RegisterView from rest_auth.registration.views import RegisterView
from fuzzywuzzy import fuzz, process
from collections import OrderedDict
from . import models, serializers from . import models, serializers
@ -16,6 +18,53 @@ class UserViewSet(viewsets.ModelViewSet):
serializer_class = serializers.UserSerializer serializer_class = serializers.UserSerializer
search_strings = {}
def gen_search_strings():
for m in models.Member.objects.all():
string = '{} {} {} {}'.format(
m.preferred_name,
m.last_name,
m.first_name,
m.last_name,
).lower()
search_strings[string] = m.id
gen_search_strings()
class SearchViewSet(viewsets.ReadOnlyModelViewSet):
permission_classes = [AllowMetadata | permissions.IsAuthenticated]
serializer_class = serializers.OtherMemberSerializer
def get_queryset(self):
NUM_SEARCH_RESULTS = 10
queryset = models.Member.objects.all()
params = self.request.query_params
if 'q' in params and len(params['q']) >= 3:
search = params['q'].lower()
choices = search_strings.keys()
# get exact starts with matches
results = [x for x in choices if x.startswith(search)]
# then get exact substring matches
results += [x for x in choices if search in x]
# then get fuzzy matches
fuzzy_results = process.extract(search, choices, limit=NUM_SEARCH_RESULTS, scorer=fuzz.token_set_ratio)
results += [x[0] for x in fuzzy_results]
# remove dupes
results = list(OrderedDict.fromkeys(results))
result_ids = [search_strings[x] for x in results]
result_objects = [queryset.get(id=x) for x in result_ids]
queryset = result_objects
else:
queryset = queryset.order_by('-vetted_date')
return queryset[:NUM_SEARCH_RESULTS]
class MemberViewSet(viewsets.ModelViewSet): class MemberViewSet(viewsets.ModelViewSet):
permission_classes = [AllowMetadata | permissions.IsAuthenticated] permission_classes = [AllowMetadata | permissions.IsAuthenticated]
http_method_names = ['options', 'head', 'get', 'put', 'patch'] http_method_names = ['options', 'head', 'get', 'put', 'patch']

View File

@ -10,6 +10,7 @@ router.register(r'users', views.UserViewSet)
router.register(r'members', views.MemberViewSet, basename='member') router.register(r'members', views.MemberViewSet, basename='member')
router.register(r'courses', views.CourseViewSet, basename='course') router.register(r'courses', views.CourseViewSet, basename='course')
router.register(r'sessions', views.SessionViewSet, basename='session') router.register(r'sessions', views.SessionViewSet, basename='session')
router.register(r'search', views.SearchViewSet, basename='search')
#router.register(r'me', views.FullMemberView, basename='fullmember') #router.register(r'me', views.FullMemberView, basename='fullmember')
#router.register(r'registration', views.RegistrationViewSet, basename='register') #router.register(r'registration', views.RegistrationViewSet, basename='register')

View File

@ -6,8 +6,12 @@ from apiserver.api import models, old_models
MEMBER_FIELDS = [ MEMBER_FIELDS = [
'id', 'id',
'first_name',
'last_name',
'preferred_name', 'preferred_name',
'status',
'phone', 'phone',
'expire_date',
'current_start_date', 'current_start_date',
'application_date', 'application_date',
'vetted_date', 'vetted_date',

View File

@ -1,11 +1,23 @@
argon2-cffi==19.2.0 argon2-cffi==19.2.0
asgiref==3.2.3 asgiref==3.2.3
certifi==2019.11.28
cffi==1.13.2 cffi==1.13.2
chardet==3.0.4
defusedxml==0.6.0
Django==3.0.2 Django==3.0.2
django-allauth==0.41.0
django-rest-auth==0.9.5 django-rest-auth==0.9.5
djangorestframework==3.11.0 djangorestframework==3.11.0
fuzzywuzzy==0.17.0
idna==2.8
oauthlib==3.1.0
pkg-resources==0.0.0 pkg-resources==0.0.0
pycparser==2.19 pycparser==2.19
python-Levenshtein==0.12.0
python3-openid==3.1.0
pytz==2019.3 pytz==2019.3
requests==2.22.0
requests-oauthlib==1.3.0
six==1.13.0 six==1.13.0
sqlparse==0.3.0 sqlparse==0.3.0
urllib3==1.25.7