StudE-Backend/stude/student_status/serializers.py

80 lines
3.3 KiB
Python
Raw Normal View History

2023-08-15 00:45:00 +08:00
from rest_framework import serializers, exceptions
from .models import StudentStatus
from subjects.models import Subject
from django.contrib.gis.geos import Point
from drf_extra_fields.geo_fields import PointField
from landmarks.models import Landmark
2023-06-26 22:06:05 +08:00
class StudentStatusSerializer(serializers.ModelSerializer):
subject = serializers.SlugRelatedField(
queryset=Subject.objects.all(), slug_field='name', required=True)
2023-07-01 16:09:20 +08:00
user = serializers.CharField(source='user.full_name', read_only=True)
2023-08-06 14:35:39 +08:00
location = PointField(required=True)
landmark = serializers.SlugRelatedField(
queryset=Landmark.objects.all(), many=False, slug_field='name', required=False, allow_null=True)
timestamp = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
2023-08-07 15:36:37 +08:00
active = serializers.BooleanField(required=True)
2023-06-27 13:40:31 +08:00
2023-06-26 22:06:05 +08:00
class Meta:
model = StudentStatus
fields = ['user', 'subject', 'location',
'timestamp', 'active', 'study_group', 'landmark']
read_only_fields = ['user', 'landmark']
def create(self, validated_data):
user = self.context['request'].user
2023-06-27 13:40:31 +08:00
student_status = StudentStatus.objects.create(
user=user, defaults=validated_data)
return student_status
2023-07-01 16:09:20 +08:00
2023-06-27 13:40:31 +08:00
def update(self, instance, validated_data):
2023-08-07 15:16:57 +08:00
2023-06-27 13:40:31 +08:00
active = validated_data.get('active', None)
2023-08-07 15:37:47 +08:00
# subject = validated_data.get('subject', None)
2023-06-27 13:40:31 +08:00
2023-08-07 15:37:47 +08:00
# If status is set as false in the request, clear the student status
if active is False:
validated_data['location'] = Point(0, 0)
2023-06-27 13:40:31 +08:00
validated_data['subject'] = None
validated_data['landmark'] = None
validated_data['study_group'] = []
else:
2023-08-15 00:45:00 +08:00
if 'subject' not in validated_data:
raise serializers.ValidationError(
{'subject': 'This field may not be empty if active is true'})
# To-do: Add geofencing to ensure locations are always within USTP
# Check each landmark to see if our location is within it
for landmark in Landmark.objects.all():
if landmark.location.contains(validated_data['location']):
validated_data['landmark'] = landmark
break
2023-06-27 13:40:31 +08:00
2023-07-01 16:09:20 +08:00
return super().update(instance, validated_data)
class StudentStatusLocationSerializer(serializers.ModelSerializer):
user = serializers.CharField(source='user.full_name', read_only=True)
subject = serializers.SlugRelatedField(
queryset=Subject.objects.all(), slug_field='name', required=True)
location = PointField(required=True)
distance = serializers.SerializerMethodField()
landmark = serializers.SlugRelatedField(
queryset=Landmark.objects.all(), many=False, slug_field='name', required=False, allow_null=True)
class Meta:
model = StudentStatus
fields = ['user', 'location', 'distance',
'subject', 'active', 'study_group', 'landmark']
read_only_fields = ['user', 'distance', 'subject',
'active', 'study_group', 'landmark']
def get_distance(self, obj):
return obj.distance.km
def to_representation(self, instance):
representation = super().to_representation(instance)
representation['distance'] = self.get_distance(instance)
return representation