Implemented geofencing logic for student_status and study_groups with landmark labels

This commit is contained in:
Keannu Christian Bernasol 2023-07-14 23:55:54 +08:00
parent 7938c3ceef
commit a67ea5cd8a
9 changed files with 85 additions and 27 deletions

View file

@ -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(

View file

@ -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)

View file

@ -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'),
),
]

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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