From 0436f8082f9ce1fbd41b7a991a700f7cce9c7ef3 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Fri, 1 Sep 2023 14:09:19 +0800 Subject: [PATCH] Added initial serializers for filtering student statuses --- stude/student_status/serializers.py | 11 +++++++- stude/student_status/urls.py | 9 ++++++- stude/student_status/views.py | 40 +++++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/stude/student_status/serializers.py b/stude/student_status/serializers.py index 1b60814..59dcbc7 100644 --- a/stude/student_status/serializers.py +++ b/stude/student_status/serializers.py @@ -20,7 +20,7 @@ class StudentStatusSerializer(serializers.ModelSerializer): class Meta: model = StudentStatus fields = ['user', 'subject', 'location', - 'timestamp', 'active', 'landmark'] + 'timestamp', 'active', 'study_group', 'landmark'] read_only_fields = ['user', 'landmark'] def create(self, validated_data): @@ -39,6 +39,7 @@ class StudentStatusSerializer(serializers.ModelSerializer): validated_data['location'] = Point(0, 0) validated_data['subject'] = None validated_data['landmark'] = None + validated_data['study_group'] = None else: if 'subject' not in validated_data: raise serializers.ValidationError( @@ -51,3 +52,11 @@ class StudentStatusSerializer(serializers.ModelSerializer): break return super().update(instance, validated_data) + + +class StudentStatusLocationSerializer(serializers.ModelSerializer): + location = PointField(required=True) + + class Meta: + model = StudentStatus + fields = ['location'] diff --git a/stude/student_status/urls.py b/stude/student_status/urls.py index ba5d6fa..496e0ab 100644 --- a/stude/student_status/urls.py +++ b/stude/student_status/urls.py @@ -1,8 +1,15 @@ from django.urls import path, include from rest_framework.routers import DefaultRouter -from .views import StudentStatusAPIView, ActiveStudentStatusListAPIView +from .views import StudentStatusAPIView, ActiveStudentStatusListAPIView, StudentStatusListByStudentStatusLocation, StudentStatusListByCurrentLocation + +router = DefaultRouter() +router.register(r'filter/near_current_location', StudentStatusListByCurrentLocation, + basename='Student Status based on current location') urlpatterns = [ path('self/', StudentStatusAPIView.as_view()), path('list/', ActiveStudentStatusListAPIView.as_view()), + path('filter/near_student_status', + StudentStatusListByStudentStatusLocation.as_view()), + path('', include(router.urls)), ] diff --git a/stude/student_status/views.py b/stude/student_status/views.py index 06706b6..cc6ff18 100644 --- a/stude/student_status/views.py +++ b/stude/student_status/views.py @@ -1,8 +1,11 @@ from django.shortcuts import get_object_or_404 -from rest_framework import generics, viewsets +from requests import Response +from rest_framework import generics, viewsets, exceptions from rest_framework.permissions import IsAuthenticated +from django.contrib.gis.db.models.functions import Distance +from django.contrib.gis.geos import fromstr from .models import StudentStatus -from .serializers import StudentStatusSerializer +from .serializers import StudentStatusLocationSerializer, StudentStatusSerializer class StudentStatusAPIView(generics.RetrieveUpdateAPIView): @@ -23,3 +26,36 @@ class ActiveStudentStatusListAPIView(generics.ListAPIView): def get_queryset(self): user = self.request.user return StudentStatus.objects.filter(active=True and user != user) + + +class StudentStatusListByStudentStatusLocation(generics.ListAPIView): + serializer_class = StudentStatusSerializer + permission_classes = [IsAuthenticated] + + def get_queryset(self): + user = self.request.user + user_status = StudentStatus.objects.filter(user=user).first() + print('User Location: ', user_status.location) + if user_status.location is None: + raise exceptions.ValidationError("User location is not set") + user_location = fromstr( + user_status.location, srid=4326) + + return StudentStatus.objects.filter(subject__in=user.subjects.all()).annotate(distance=Distance('location', user_location)).filter(distance__lte=50) + + +class StudentStatusListByCurrentLocation(viewsets.ViewSet): + serializer_class = StudentStatusLocationSerializer + # permission_classes = [IsAuthenticated] + + def create(self, request): + user = self.request.user + location_str = request.data.get('location') + if not location_str: + raise exceptions.ValidationError("Location is required") + + user_location = fromstr(location_str, srid=4326) + queryset = StudentStatus.objects.filter(subject__in=user.subjects.all()).annotate( + distance=Distance('location', user_location)).filter(distance__lte=50) + serializer = StudentStatusSerializer(queryset, many=True) + return Response(serializer.data)