diff --git a/app/conf/api.py b/app/conf/api.py index 189e6e9..ad55947 100644 --- a/app/conf/api.py +++ b/app/conf/api.py @@ -1,8 +1,9 @@ from django.urls import path -from search.api.views import SearchApi, HintApi +from search.api.views import SearchApi, HintApi, AutoCompleteApi urlpatterns = [ path("search", SearchApi.as_view(), name="search_api"), - path("hint", HintApi.as_view(), name="hint api") + path("hint", HintApi.as_view(), name="hint api"), + path('autocomplete_schema', AutoCompleteApi.as_view(), name='autocomplete api') ] diff --git a/app/search/api/serializers.py b/app/search/api/serializers.py index 107d83b..aa79b4b 100644 --- a/app/search/api/serializers.py +++ b/app/search/api/serializers.py @@ -1,4 +1,6 @@ from rest_framework import serializers +from django.core.validators import MinLengthValidator, MinValueValidator + class SearchSerializer(serializers.Serializer): @@ -31,3 +33,16 @@ class HintRequestSerializer(serializers.Serializer): class HintResponseSerializer(serializers.Serializer): type = serializers.CharField() content = serializers.CharField() + + +class AutoCompleteRequestSerializer(serializers.Serializer): + content = serializers.CharField(validators=[MinLengthValidator(3)]) + + +class AutoCompleteSerializerNode(serializers.Serializer): + coordinate = serializers.IntegerField(validators=[MinValueValidator(0)]) + value = HintResponseSerializer() + + +class AutoCompleteResponseSerializer(serializers.Serializer): + nodes = serializers.ListField(child=AutoCompleteSerializerNode()) diff --git a/app/search/api/views.py b/app/search/api/views.py index 4e50995..81e5993 100644 --- a/app/search/api/views.py +++ b/app/search/api/views.py @@ -5,12 +5,16 @@ from rest_framework.response import Response from rest_framework.views import APIView from search.api.serializers import HintRequestSerializer -from search.api.serializers import SearchSerializer, ResponseSerializer, HintResponseSerializer +from search.api.serializers import SearchSerializer, ResponseSerializer, HintResponseSerializer, AutoCompleteRequestSerializer, AutoCompleteResponseSerializer from search.services.search import process_string +from search.services.autocomplete_schema import autocomplete_schema + from search.services.hints import get_hints user_response = openapi.Response("search results", ResponseSerializer) hint_response = openapi.Response("hints", HintResponseSerializer) +autocomplete_response = openapi.Response("autocomplete schema", AutoCompleteResponseSerializer) + class SearchApi(APIView): @swagger_auto_schema(request_body=SearchSerializer, responses={200: user_response}) @@ -33,4 +37,15 @@ class HintApi(APIView): 'value': serializer.data['content'] }, status=status.HTTP_200_OK - ) \ No newline at end of file + ) + +class AutoCompleteApi(APIView): + @swagger_auto_schema(request_body=AutoCompleteRequestSerializer, responses={200: autocomplete_response}) + def post(self, request, format=None): + serializer = AutoCompleteRequestSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + return Response( + { + 'nodes': autocomplete_schema(serializer.data['content']) + }, status=status.HTTP_200_OK + ) diff --git a/app/search/services/autocomplete_schema.py b/app/search/services/autocomplete_schema.py new file mode 100644 index 0000000..9e6b185 --- /dev/null +++ b/app/search/services/autocomplete_schema.py @@ -0,0 +1,37 @@ +from search.models import Product, Category, Characteristic + +def autocomplete_schema(val: str): + schema = [] + schema.extend( + [ + { + 'coordinate': product['name'].index(val), + 'value': { + 'type': 'Name', + 'value': product['name'], + } + } for product in Product.objects.filter(name__contains=val).values('name')] + ) + schema.extend( + [ + { + 'coordinate': cat['name'].index(val), + 'value': { + 'type': 'Category', + 'value': cat['name'] + } + } for cat in Category.objects.filter(name__contains=val).values('name') + ] + ) + schema.extend( + [ + { + 'coordinate': char.name.index(val), + 'value': { + 'type': char.name, + 'value': char.value + } + } for char in Characteristic.objects.filter(name__contains=val).values('name', 'value') + ] + ) + return schema