mirror of
https://github.com/lemeow125/StudE-Backend.git
synced 2024-11-16 22:09:25 +08:00
Offloaded study group radius calculation to backend and fixed study groups serializer
This commit is contained in:
parent
018475b92c
commit
50fdebf222
2 changed files with 39 additions and 18 deletions
|
@ -14,6 +14,7 @@ class CustomUserKeyRelatedField(serializers.PrimaryKeyRelatedField):
|
|||
|
||||
|
||||
class StudyGroupSerializer(serializers.ModelSerializer):
|
||||
name = serializers.CharField()
|
||||
users = CustomUserKeyRelatedField(
|
||||
queryset=CustomUser.objects.all(), many=True)
|
||||
subject = serializers.SlugRelatedField(
|
||||
|
@ -21,6 +22,7 @@ class StudyGroupSerializer(serializers.ModelSerializer):
|
|||
location = PointField()
|
||||
landmark = serializers.SlugRelatedField(
|
||||
queryset=Landmark.objects.all(), many=False, slug_field='name', required=False, allow_null=True)
|
||||
radius = serializers.FloatField()
|
||||
|
||||
def create(self, validated_data):
|
||||
user = self.context['request'].user
|
||||
|
@ -40,7 +42,7 @@ class StudyGroupSerializer(serializers.ModelSerializer):
|
|||
class Meta:
|
||||
model = StudyGroup
|
||||
fields = '__all__'
|
||||
read_only_fields = ['landmark']
|
||||
read_only_fields = ['landmark', 'radius']
|
||||
|
||||
|
||||
class StudyGroupMembershipSerializer(serializers.ModelSerializer):
|
||||
|
|
|
@ -4,11 +4,12 @@ from rest_framework.exceptions import PermissionDenied
|
|||
from rest_framework.permissions import IsAuthenticated
|
||||
from .serializers import StudyGroupSerializer
|
||||
from .models import StudyGroup
|
||||
from subjects.models import Subject
|
||||
from subjects.models import Subject, SubjectInstance
|
||||
from student_status.models import StudentStatus
|
||||
from rest_framework import generics, viewsets, exceptions
|
||||
from django.contrib.gis.geos import fromstr
|
||||
from django.contrib.gis.db.models.functions import Distance
|
||||
|
||||
# Create your views here.
|
||||
|
||||
|
||||
|
@ -20,6 +21,11 @@ class StudyGroupListView(generics.ListAPIView):
|
|||
def get_queryset(self):
|
||||
user = self.request.user
|
||||
|
||||
if not user.is_student:
|
||||
raise PermissionDenied(
|
||||
"You must be a student to view study groups"
|
||||
)
|
||||
|
||||
if not user.is_student:
|
||||
raise PermissionDenied(
|
||||
"You must be a student to view study groups"
|
||||
|
@ -29,15 +35,14 @@ class StudyGroupListView(generics.ListAPIView):
|
|||
user_course = user.course
|
||||
print(user_course)
|
||||
|
||||
# Get subject names related to the user's course
|
||||
subject_names = Subject.objects.filter(
|
||||
course=user_course
|
||||
).values_list('subject', flat=True)
|
||||
# Get the subject name of the student's subjects from SubjectInstance
|
||||
user_subject_names = user.subjects.values_list('subject', flat=True)
|
||||
print('user subjects:', user_subject_names)
|
||||
# Get the corresponding Subject models
|
||||
user_subjects = Subject.objects.filter(name__in=user_subject_names)
|
||||
# Now fetch the StudyGroups with the matching Subject models
|
||||
studygroups = StudyGroup.objects.filter(subject__in=user_subjects)
|
||||
|
||||
print(subject_names)
|
||||
|
||||
# Now fetch the StudyGroups with the matching subject names
|
||||
studygroups = StudyGroup.objects.filter(subject_name__in=subject_names)
|
||||
return studygroups
|
||||
|
||||
|
||||
|
@ -64,16 +69,30 @@ class StudyGroupListNearView(generics.ListAPIView):
|
|||
user_course = user.course
|
||||
print(user_course)
|
||||
|
||||
# Get subject names related to the user's course
|
||||
subject_names = Subject.objects.filter(
|
||||
course=user_course
|
||||
).values_list('subject', flat=True)
|
||||
# Get the subject name of the student's subjects from SubjectInstance
|
||||
user_subject_names = user.subjects.values_list('subject', flat=True)
|
||||
# Get the corresponding Subject models
|
||||
user_subjects = Subject.objects.filter(name__in=user_subject_names)
|
||||
|
||||
print(subject_names)
|
||||
# Now fetch the StudyGroups with the matching Subject models that are within 100m
|
||||
studygroups = StudyGroup.objects.filter(subject__in=user_subjects).annotate(
|
||||
distance=Distance('location', user_location)).filter(distance__lte=100)
|
||||
|
||||
for group in studygroups:
|
||||
# Get all StudentStatus locations of the group
|
||||
group_locations = group.users.values_list('location', flat=True)
|
||||
# Convert string locations to GEOSGeometry objects
|
||||
point_locations = [fromstr(loc, srid=4326)
|
||||
for loc in group_locations]
|
||||
# Calculate distances between every pair of locations
|
||||
distances = [(loc1.distance(
|
||||
loc2)*100000)for loc1 in point_locations for loc2 in point_locations]
|
||||
# Get the maximum distance
|
||||
group_radius = max(distances) if distances else 0
|
||||
group_radius = max(group_radius, 15)
|
||||
# Annotate the group with the radius
|
||||
group.radius = group_radius
|
||||
|
||||
# Now fetch the StudyGroups with the matching subject names that are within 50m
|
||||
studygroups = StudyGroup.objects.filter(subject_name__in=subject_names).annotate(
|
||||
distance=Distance('location', user_location)).filter(distance__lte=50)
|
||||
return studygroups
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue