mirror of
https://github.com/lemeow125/StudE-Backend.git
synced 2025-06-28 16:25:44 +08:00
Implemented geofencing logic for student_status and study_groups with landmark labels
This commit is contained in:
parent
7938c3ceef
commit
a67ea5cd8a
9 changed files with 85 additions and 27 deletions
|
@ -8,7 +8,7 @@ from django.dispatch import receiver
|
|||
|
||||
class Landmark(models.Model):
|
||||
name = models.CharField(max_length=64)
|
||||
location = gis_models.PolygonField()
|
||||
location = gis_models.PolygonField(srid=4326)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
@ -178,7 +178,7 @@ def populate_landmarks(sender, **kwargs):
|
|||
'POLYGON ((124.655534 8.485857, 124.655629 8.485588, 124.655795 8.485647, 124.655755 8.485757, 124.656271 8.485946, 124.656212 8.486104, 124.655534 8.485857))',
|
||||
srid=SRID
|
||||
)
|
||||
)
|
||||
)
|
||||
Landmark.objects.get_or_create(
|
||||
name='Science Complex',
|
||||
location=GEOSGeometry(
|
||||
|
|
|
@ -2,4 +2,14 @@ from django.contrib import admin
|
|||
from .models import StudentStatus
|
||||
from leaflet.admin import LeafletGeoAdmin
|
||||
|
||||
admin.site.register(StudentStatus, LeafletGeoAdmin)
|
||||
|
||||
class StudentStatusAdmin(LeafletGeoAdmin):
|
||||
# define which fields are required
|
||||
def get_form(self, request, obj=None, **kwargs):
|
||||
form = super(StudentStatusAdmin, self).get_form(request, obj, **kwargs)
|
||||
form.base_fields['landmark'].required = False
|
||||
return form
|
||||
|
||||
|
||||
# Register the new StudentStatus model
|
||||
admin.site.register(StudentStatus, StudentStatusAdmin)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# Generated by Django 4.2.3 on 2023-07-14 14:51
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('landmarks', '0001_initial'),
|
||||
('student_status', '0002_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='studentstatus',
|
||||
name='landmark',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='landmarks.landmark'),
|
||||
),
|
||||
]
|
|
@ -9,11 +9,13 @@ from django.contrib.gis.geos import Point
|
|||
class StudentStatus(models.Model):
|
||||
user = models.OneToOneField(
|
||||
CustomUser, on_delete=models.CASCADE, primary_key=True)
|
||||
location = gis_models.PointField(blank=True, null=True)
|
||||
location = gis_models.PointField(blank=True, null=True, srid=4326)
|
||||
subject = models.ForeignKey(
|
||||
'subjects.Subject', on_delete=models.SET_NULL, null=True)
|
||||
active = models.BooleanField(default=False)
|
||||
timestamp = models.DateField(auto_now_add=True)
|
||||
landmark = models.ForeignKey(
|
||||
'landmarks.Landmark', on_delete=models.SET_NULL, null=True)
|
||||
study_group = models.ManyToManyField(
|
||||
'study_groups.StudyGroup', through='study_groups.StudyGroupMembership', blank=True)
|
||||
|
||||
|
|
|
@ -2,17 +2,22 @@ from rest_framework import serializers
|
|||
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
|
||||
|
||||
|
||||
class StudentStatusSerializer(serializers.ModelSerializer):
|
||||
subject = serializers.SlugRelatedField(
|
||||
queryset=Subject.objects.all(), slug_field='name', required=True)
|
||||
user = serializers.CharField(source='user.full_name', read_only=True)
|
||||
location = PointField()
|
||||
landmark = serializers.SlugRelatedField(
|
||||
queryset=Landmark.objects.all(), many=False, slug_field='name', required=False, allow_null=True)
|
||||
|
||||
class Meta:
|
||||
model = StudentStatus
|
||||
fields = '__all__'
|
||||
read_only_fields = ['user']
|
||||
read_only_fields = ['user', 'landmark']
|
||||
|
||||
def create(self, validated_data):
|
||||
user = self.context['request'].user
|
||||
|
@ -26,5 +31,12 @@ class StudentStatusSerializer(serializers.ModelSerializer):
|
|||
if active is not None and active is False:
|
||||
validated_data['location'] = Point(0, 0)
|
||||
validated_data['subject'] = None
|
||||
validated_data['landmark'] = None
|
||||
else:
|
||||
# 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
|
||||
|
||||
return super().update(instance, validated_data)
|
||||
|
|
|
@ -9,7 +9,7 @@ class StudyGroup(models.Model):
|
|||
name = models.CharField(max_length=48)
|
||||
users = models.ManyToManyField(
|
||||
'student_status.StudentStatus', through='StudyGroupMembership')
|
||||
location = gis_models.PointField(blank=True, null=True)
|
||||
location = gis_models.PointField(blank=True, null=True, srid=4326)
|
||||
subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
|
||||
active = models.BooleanField(default=False)
|
||||
timestamp = models.DateField(auto_now_add=True)
|
||||
|
|
|
@ -2,6 +2,7 @@ from rest_framework import serializers
|
|||
from .models import StudyGroup, StudyGroupMembership
|
||||
from accounts.models import CustomUser
|
||||
from subjects.models import Subject
|
||||
from drf_extra_fields.geo_fields import PointField
|
||||
|
||||
|
||||
class StudyGroupSerializer(serializers.ModelSerializer):
|
||||
|
@ -9,6 +10,7 @@ class StudyGroupSerializer(serializers.ModelSerializer):
|
|||
queryset=CustomUser.objects.all(), many=True, slug_field='name', required=False, allow_null=True)
|
||||
subject = serializers.SlugRelatedField(
|
||||
many=False, slug_field='name', queryset=Subject.objects.all(), required=True, allow_null=False)
|
||||
location = PointField()
|
||||
|
||||
class Meta:
|
||||
model = StudyGroup
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue