Changed foreign key field value to reference the required string directly rather than id from StudentStatus and CustomUser with Subjects

This commit is contained in:
Keannu Bernasol 2023-09-06 18:13:21 +08:00
parent 63d16eae17
commit fc031e9e51
5 changed files with 68 additions and 6 deletions

View file

@ -0,0 +1,20 @@
# Generated by Django 4.2.3 on 2023-09-05 12:19
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('subjects', '0002_alter_subject_name_alter_subjectinstance_subject'),
('student_status', '0002_initial'),
]
operations = [
migrations.AlterField(
model_name='studentstatus',
name='subject',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='subjects.subject', to_field='name'),
),
]

View file

@ -11,7 +11,7 @@ class StudentStatus(models.Model):
CustomUser, on_delete=models.CASCADE, primary_key=True) CustomUser, on_delete=models.CASCADE, primary_key=True)
location = gis_models.PointField(blank=True, null=True, srid=4326) location = gis_models.PointField(blank=True, null=True, srid=4326)
subject = models.ForeignKey( subject = models.ForeignKey(
'subjects.Subject', on_delete=models.SET_NULL, null=True) 'subjects.Subject', on_delete=models.SET_NULL, null=True, to_field='name')
active = models.BooleanField(default=False) active = models.BooleanField(default=False)
timestamp = models.DateTimeField(auto_now_add=True) timestamp = models.DateTimeField(auto_now_add=True)
landmark = models.ForeignKey( landmark = models.ForeignKey(

View file

@ -7,6 +7,7 @@ from django.contrib.gis.db.models.functions import Distance
from django.contrib.gis.geos import fromstr from django.contrib.gis.geos import fromstr
from .models import StudentStatus from .models import StudentStatus
from .serializers import StudentStatusLocationSerializer, StudentStatusSerializer from .serializers import StudentStatusLocationSerializer, StudentStatusSerializer
from subjects.models import Subject, SubjectInstance
class StudentStatusAPIView(generics.RetrieveUpdateAPIView): class StudentStatusAPIView(generics.RetrieveUpdateAPIView):
@ -26,7 +27,7 @@ class ActiveStudentStatusListAPIView(generics.ListAPIView):
def get_queryset(self): def get_queryset(self):
user = self.request.user user = self.request.user
return StudentStatus.objects.filter(active=True and user != user) return StudentStatus.objects.exclude(user=user).filter(active=True)
class StudentStatusListByStudentStatusLocation(generics.ListAPIView): class StudentStatusListByStudentStatusLocation(generics.ListAPIView):
@ -44,7 +45,15 @@ class StudentStatusListByStudentStatusLocation(generics.ListAPIView):
if user_status.active is False: if user_status.active is False:
raise exceptions.ValidationError("Student Status is not active") raise exceptions.ValidationError("Student Status is not active")
return StudentStatus.objects.filter(active=True and user != user).filter(subject__in=user.subjects.all()).annotate(distance=Distance('location', user_location)).filter(distance__lte=50) # Get names of all subjects of the user
user_subject_names = user.subjects.values_list('subject', flat=True)
# Exclude user
# Filter those only with the same subjects as the user
# Annotate the queryset with distance to the user
# Then filter so that only those within 50m remain
return StudentStatus.objects.exclude(user=user).filter(active=True).filter(
subject__name__in=user_subject_names).annotate(distance=Distance('location', user_location)).filter(distance__lte=50)
class StudentStatusListByCurrentLocation(viewsets.ViewSet): class StudentStatusListByCurrentLocation(viewsets.ViewSet):
@ -60,8 +69,17 @@ class StudentStatusListByCurrentLocation(viewsets.ViewSet):
if not location_str: if not location_str:
raise exceptions.ValidationError("Location is required") raise exceptions.ValidationError("Location is required")
# Parse user location from the POST request
user_location = fromstr(location_str, srid=4326) user_location = fromstr(location_str, srid=4326)
queryset = StudentStatus.objects.filter(active=True and user != user).filter(subject__in=user.subjects.all()).annotate(
# Get names of all subjects of the user
user_subject_names = user.subjects.values_list('subject', flat=True)
# Exclude user
# Filter those only with the same subjects as the user
# Annotate the queryset with distance to the user
# Then filter so that only those within 50m remain
queryset = StudentStatus.objects.exclude(user=user).filter(active=True).filter(subject__name__in=user_subject_names).annotate(
distance=Distance('location', user_location)).filter(distance__lte=50) distance=Distance('location', user_location)).filter(distance__lte=50)
serializer = StudentStatusLocationSerializer(queryset, many=True) serializer = StudentStatusLocationSerializer(queryset, many=True)
return Response(serializer.data) return Response(serializer.data)

View file

@ -0,0 +1,24 @@
# Generated by Django 4.2.3 on 2023-09-05 12:19
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('subjects', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='subject',
name='name',
field=models.CharField(max_length=64, unique=True),
),
migrations.AlterField(
model_name='subjectinstance',
name='subject',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='subjects.subject', to_field='name'),
),
]

View file

@ -12,7 +12,7 @@ from semesters.models import Semester
class Subject(models.Model): class Subject(models.Model):
name = models.CharField(max_length=64) name = models.CharField(max_length=64, unique=True)
students = models.ManyToManyField( students = models.ManyToManyField(
CustomUser, blank=True) CustomUser, blank=True)
@ -22,7 +22,7 @@ class Subject(models.Model):
class SubjectInstance(models.Model): class SubjectInstance(models.Model):
subject = models.ForeignKey( subject = models.ForeignKey(
Subject, on_delete=models.CASCADE) Subject, on_delete=models.CASCADE, to_field='name')
code = models.CharField(max_length=16) code = models.CharField(max_length=16)
course = models.ForeignKey( course = models.ForeignKey(
Course, on_delete=models.CASCADE) Course, on_delete=models.CASCADE)