mirror of
https://github.com/lemeow125/StudE-Backend.git
synced 2024-11-17 06:19:24 +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
1
Pipfile
1
Pipfile
|
@ -15,6 +15,7 @@ daphne = "*"
|
|||
psycopg2 = "*"
|
||||
gdal = {path = "./packages/GDAL-3.4.3-cp311-cp311-win_amd64.whl"}
|
||||
django-leaflet = "*"
|
||||
django-extra-fields = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
|
53
Pipfile.lock
generated
53
Pipfile.lock
generated
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "efd1134f98df71c3c1209f70d5d962b6609fe23b044b57f80bba89db477b549f"
|
||||
"sha256": "975af7eaaedebb1c31a1828fdf307574edc293e0de15ecfd9cf7107f98d642f5"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -221,28 +221,32 @@
|
|||
},
|
||||
"cryptography": {
|
||||
"hashes": [
|
||||
"sha256:059e348f9a3c1950937e1b5d7ba1f8e968508ab181e75fc32b879452f08356db",
|
||||
"sha256:1a5472d40c8f8e91ff7a3d8ac6dfa363d8e3138b961529c996f3e2df0c7a411a",
|
||||
"sha256:1a8e6c2de6fbbcc5e14fd27fb24414507cb3333198ea9ab1258d916f00bc3039",
|
||||
"sha256:1fee5aacc7367487b4e22484d3c7e547992ed726d14864ee33c0176ae43b0d7c",
|
||||
"sha256:5d092fdfedaec4cbbffbf98cddc915ba145313a6fdaab83c6e67f4e6c218e6f3",
|
||||
"sha256:5f0ff6e18d13a3de56f609dd1fd11470918f770c6bd5d00d632076c727d35485",
|
||||
"sha256:7bfc55a5eae8b86a287747053140ba221afc65eb06207bedf6e019b8934b477c",
|
||||
"sha256:7fa01527046ca5facdf973eef2535a27fec4cb651e4daec4d043ef63f6ecd4ca",
|
||||
"sha256:8dde71c4169ec5ccc1087bb7521d54251c016f126f922ab2dfe6649170a3b8c5",
|
||||
"sha256:8f4ab7021127a9b4323537300a2acfb450124b2def3756f64dc3a3d2160ee4b5",
|
||||
"sha256:948224d76c4b6457349d47c0c98657557f429b4e93057cf5a2f71d603e2fc3a3",
|
||||
"sha256:9a6c7a3c87d595608a39980ebaa04d5a37f94024c9f24eb7d10262b92f739ddb",
|
||||
"sha256:b46e37db3cc267b4dea1f56da7346c9727e1209aa98487179ee8ebed09d21e43",
|
||||
"sha256:b4ceb5324b998ce2003bc17d519080b4ec8d5b7b70794cbd2836101406a9be31",
|
||||
"sha256:cb33ccf15e89f7ed89b235cff9d49e2e62c6c981a6061c9c8bb47ed7951190bc",
|
||||
"sha256:d198820aba55660b4d74f7b5fd1f17db3aa5eb3e6893b0a41b75e84e4f9e0e4b",
|
||||
"sha256:d34579085401d3f49762d2f7d6634d6b6c2ae1242202e860f4d26b046e3a1006",
|
||||
"sha256:eb8163f5e549a22888c18b0d53d6bb62a20510060a22fd5a995ec8a05268df8a",
|
||||
"sha256:f73bff05db2a3e5974a6fd248af2566134d8981fd7ab012e5dd4ddb1d9a70699"
|
||||
"sha256:01f1d9e537f9a15b037d5d9ee442b8c22e3ae11ce65ea1f3316a41c78756b711",
|
||||
"sha256:079347de771f9282fbfe0e0236c716686950c19dee1b76240ab09ce1624d76d7",
|
||||
"sha256:182be4171f9332b6741ee818ec27daff9fb00349f706629f5cbf417bd50e66fd",
|
||||
"sha256:192255f539d7a89f2102d07d7375b1e0a81f7478925b3bc2e0549ebf739dae0e",
|
||||
"sha256:2a034bf7d9ca894720f2ec1d8b7b5832d7e363571828037f9e0c4f18c1b58a58",
|
||||
"sha256:342f3767e25876751e14f8459ad85e77e660537ca0a066e10e75df9c9e9099f0",
|
||||
"sha256:439c3cc4c0d42fa999b83ded80a9a1fb54d53c58d6e59234cfe97f241e6c781d",
|
||||
"sha256:49c3222bb8f8e800aead2e376cbef687bc9e3cb9b58b29a261210456a7783d83",
|
||||
"sha256:674b669d5daa64206c38e507808aae49904c988fa0a71c935e7006a3e1e83831",
|
||||
"sha256:7a9a3bced53b7f09da251685224d6a260c3cb291768f54954e28f03ef14e3766",
|
||||
"sha256:7af244b012711a26196450d34f483357e42aeddb04128885d95a69bd8b14b69b",
|
||||
"sha256:7d230bf856164de164ecb615ccc14c7fc6de6906ddd5b491f3af90d3514c925c",
|
||||
"sha256:84609ade00a6ec59a89729e87a503c6e36af98ddcd566d5f3be52e29ba993182",
|
||||
"sha256:9a6673c1828db6270b76b22cc696f40cde9043eb90373da5c2f8f2158957f42f",
|
||||
"sha256:9b6d717393dbae53d4e52684ef4f022444fc1cce3c48c38cb74fca29e1f08eaa",
|
||||
"sha256:9c3fe6534d59d071ee82081ca3d71eed3210f76ebd0361798c74abc2bcf347d4",
|
||||
"sha256:a719399b99377b218dac6cf547b6ec54e6ef20207b6165126a280b0ce97e0d2a",
|
||||
"sha256:b332cba64d99a70c1e0836902720887fb4529ea49ea7f5462cf6640e095e11d2",
|
||||
"sha256:d124682c7a23c9764e54ca9ab5b308b14b18eba02722b8659fb238546de83a76",
|
||||
"sha256:d73f419a56d74fef257955f51b18d046f3506270a5fd2ac5febbfa259d6c0fa5",
|
||||
"sha256:f0dc40e6f7aa37af01aba07277d3d64d5a03dc66d682097541ec4da03cc140ee",
|
||||
"sha256:f14ad275364c8b4e525d018f6716537ae7b6d369c094805cae45300847e0894f",
|
||||
"sha256:f772610fe364372de33d76edcd313636a25684edb94cee53fd790195f5989d14"
|
||||
],
|
||||
"markers": "python_version >= '3.7'",
|
||||
"version": "==41.0.1"
|
||||
"version": "==41.0.2"
|
||||
},
|
||||
"daphne": {
|
||||
"hashes": [
|
||||
|
@ -268,6 +272,13 @@
|
|||
"index": "pypi",
|
||||
"version": "==4.2.3"
|
||||
},
|
||||
"django-extra-fields": {
|
||||
"hashes": [
|
||||
"sha256:2334e914b346c0a19a7765bf0ff7895c46cf35d5f40315a68418f44b7ddbb33b"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.0.2"
|
||||
},
|
||||
"django-leaflet": {
|
||||
"hashes": [
|
||||
"sha256:2f6dc8c7187fd22e62b6f2b7b42eed86920f81bec312aa654981ebe5bc8e0866",
|
||||
|
|
|
@ -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…
Reference in a new issue