Removed associative entity and fixed relationship between student status and study group

This commit is contained in:
Keannu Bernasol 2023-09-25 21:09:31 +08:00
parent 771300f933
commit 7dc80caee7
23 changed files with 266 additions and 253 deletions

View file

@ -1,4 +1,4 @@
# Generated by Django 4.2.3 on 2023-09-03 09:32 # Generated by Django 4.2.3 on 2023-09-25 13:07
import accounts.models import accounts.models
import django.contrib.auth.models import django.contrib.auth.models
@ -14,8 +14,8 @@ class Migration(migrations.Migration):
dependencies = [ dependencies = [
('semesters', '0001_initial'), ('semesters', '0001_initial'),
('courses', '0001_initial'),
('auth', '0012_alter_user_first_name_max_length'), ('auth', '0012_alter_user_first_name_max_length'),
('courses', '0001_initial'),
] ]
operations = [ operations = [

View file

@ -1,4 +1,4 @@
# Generated by Django 4.2.3 on 2023-09-03 09:32 # Generated by Django 4.2.3 on 2023-09-25 13:07
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
@ -9,9 +9,9 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('accounts', '0001_initial'),
('year_levels', '0001_initial'), ('year_levels', '0001_initial'),
('subjects', '0001_initial'), ('subjects', '0001_initial'),
('accounts', '0001_initial'),
('auth', '0012_alter_user_first_name_max_length'), ('auth', '0012_alter_user_first_name_max_length'),
] ]

View file

@ -1,4 +1,4 @@
# Generated by Django 4.2.3 on 2023-09-03 09:32 # Generated by Django 4.2.3 on 2023-09-25 13:07
from django.db import migrations, models from django.db import migrations, models

View file

@ -1,4 +1,4 @@
# Generated by Django 4.2.3 on 2023-09-03 09:32 # Generated by Django 4.2.3 on 2023-09-25 13:07
import django.contrib.gis.db.models.fields import django.contrib.gis.db.models.fields
from django.db import migrations, models from django.db import migrations, models

View file

@ -547,9 +547,9 @@ paths:
items: items:
$ref: '#/components/schemas/Landmark' $ref: '#/components/schemas/Landmark'
description: '' description: ''
/api/v1/messages/group_messages/: /api/v1/messages/:
get: get:
operationId: api_v1_messages_group_messages_list operationId: api_v1_messages_list
tags: tags:
- api - api
security: security:
@ -564,7 +564,7 @@ paths:
$ref: '#/components/schemas/Message' $ref: '#/components/schemas/Message'
description: '' description: ''
post: post:
operationId: api_v1_messages_group_messages_create operationId: api_v1_messages_create
tags: tags:
- api - api
requestBody: requestBody:
@ -588,14 +588,15 @@ paths:
schema: schema:
$ref: '#/components/schemas/Message' $ref: '#/components/schemas/Message'
description: '' description: ''
/api/v1/messages/group_messages/{id}/: /api/v1/messages/{id}/:
get: get:
operationId: api_v1_messages_group_messages_retrieve operationId: api_v1_messages_retrieve
parameters: parameters:
- in: path - in: path
name: id name: id
schema: schema:
type: string type: integer
description: A unique integer value identifying this message.
required: true required: true
tags: tags:
- api - api
@ -625,6 +626,48 @@ paths:
items: items:
$ref: '#/components/schemas/Semester' $ref: '#/components/schemas/Semester'
description: '' description: ''
/api/v1/student_status/filter/near_current_location/:
post:
operationId: api_v1_student_status_filter_near_current_location_create
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StudentStatusLocation'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/StudentStatusLocation'
multipart/form-data:
schema:
$ref: '#/components/schemas/StudentStatusLocation'
required: true
security:
- jwtAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/StudentStatusLocation'
description: ''
/api/v1/student_status/filter/near_student_status:
get:
operationId: api_v1_student_status_filter_near_student_status_list
tags:
- api
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/StudentStatusLocation'
description: ''
/api/v1/student_status/list/: /api/v1/student_status/list/:
get: get:
operationId: api_v1_student_status_list_list operationId: api_v1_student_status_list_list
@ -720,14 +763,96 @@ paths:
items: items:
$ref: '#/components/schemas/StudyGroup' $ref: '#/components/schemas/StudyGroup'
description: '' description: ''
/api/v1/study_groups/membership/: post:
get: operationId: api_v1_study_groups_create
operationId: api_v1_study_groups_membership_list tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StudyGroup'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/StudyGroup'
multipart/form-data:
schema:
$ref: '#/components/schemas/StudyGroup'
required: true
security:
- jwtAuth: []
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/StudyGroup'
description: ''
put:
operationId: api_v1_study_groups_update
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StudyGroup'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/StudyGroup'
multipart/form-data:
schema:
$ref: '#/components/schemas/StudyGroup'
required: true
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/StudyGroup'
description: ''
patch:
operationId: api_v1_study_groups_partial_update
tags:
- api
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/PatchedStudyGroup'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/PatchedStudyGroup'
multipart/form-data:
schema:
$ref: '#/components/schemas/PatchedStudyGroup'
security:
- jwtAuth: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/StudyGroup'
description: ''
delete:
operationId: api_v1_study_groups_destroy
tags:
- api
security:
- jwtAuth: []
responses:
'204':
description: No response body
/api/v1/study_groups/near/:
get:
operationId: api_v1_study_groups_near_list
tags: tags:
- api - api
security: security:
- jwtAuth: [] - jwtAuth: []
- {}
responses: responses:
'200': '200':
content: content:
@ -751,7 +876,7 @@ paths:
schema: schema:
type: array type: array
items: items:
$ref: '#/components/schemas/Subject' $ref: '#/components/schemas/SubjectInstance'
description: '' description: ''
/api/v1/subjects/{course_slug}: /api/v1/subjects/{course_slug}:
get: get:
@ -774,7 +899,7 @@ paths:
schema: schema:
type: array type: array
items: items:
$ref: '#/components/schemas/Subject' $ref: '#/components/schemas/SubjectInstance'
description: '' description: ''
/api/v1/subjects/{course_slug}/{year_slug}/{semester_slug}: /api/v1/subjects/{course_slug}/{year_slug}/{semester_slug}:
get: get:
@ -807,7 +932,7 @@ paths:
schema: schema:
type: array type: array
items: items:
$ref: '#/components/schemas/Subject' $ref: '#/components/schemas/SubjectInstance'
description: '' description: ''
/api/v1/subjects/all: /api/v1/subjects/all:
get: get:
@ -824,7 +949,7 @@ paths:
schema: schema:
type: array type: array
items: items:
$ref: '#/components/schemas/Subject' $ref: '#/components/schemas/SubjectInstance'
description: '' description: ''
/api/v1/year_levels/: /api/v1/year_levels/:
get: get:
@ -886,8 +1011,7 @@ components:
title: Email address title: Email address
maxLength: 254 maxLength: 254
student_id_number: student_id_number:
type: string type: integer
maxLength: 16
year_level: year_level:
type: string type: string
nullable: true nullable: true
@ -913,7 +1037,6 @@ components:
avatar: avatar:
type: string type: string
format: uri format: uri
nullable: true
first_name: first_name:
type: string type: string
maxLength: 100 maxLength: 100
@ -923,6 +1046,7 @@ components:
irregular: irregular:
type: boolean type: boolean
required: required:
- avatar
- course_shortname - course_shortname
- first_name - first_name
- last_name - last_name
@ -996,8 +1120,7 @@ components:
title: Email address title: Email address
maxLength: 254 maxLength: 254
student_id_number: student_id_number:
type: string type: integer
maxLength: 16
year_level: year_level:
type: string type: string
nullable: true nullable: true
@ -1023,7 +1146,6 @@ components:
avatar: avatar:
type: string type: string
format: uri format: uri
nullable: true
first_name: first_name:
type: string type: string
maxLength: 100 maxLength: 100
@ -1042,20 +1164,45 @@ components:
type: string type: string
location: location:
type: string type: string
timestamp:
type: string
format: date-time
active:
type: boolean
study_group:
type: integer
nullable: true
landmark: landmark:
type: string type: string
nullable: true nullable: true
PatchedStudyGroup:
type: object
properties:
id:
type: integer
readOnly: true
name:
type: string
students:
type: array
items:
type: string
subject:
type: string
location:
type: string
landmark:
type: string
nullable: true
radius:
type: number
format: double
active: active:
type: boolean type: boolean
timestamp: timestamp:
type: string type: string
format: date format: date
readOnly: true readOnly: true
study_group:
type: array
items:
type: integer
readOnly: true
Semester: Semester:
type: object type: object
properties: properties:
@ -1115,25 +1262,52 @@ components:
type: string type: string
location: location:
type: string type: string
timestamp:
type: string
format: date-time
active:
type: boolean
study_group:
type: integer
nullable: true
landmark: landmark:
type: string type: string
nullable: true nullable: true
required:
- active
- location
- subject
- timestamp
- user
StudentStatusLocation:
type: object
properties:
user:
type: string
readOnly: true
location:
type: string
distance:
type: string
readOnly: true
subject:
type: string
active: active:
type: boolean type: boolean
timestamp:
type: string
format: date
readOnly: true readOnly: true
study_group: study_group:
type: array type: integer
items:
type: integer
readOnly: true readOnly: true
nullable: true
landmark:
type: string
nullable: true
required: required:
- active
- distance
- location - location
- study_group - study_group
- subject - subject
- timestamp
- user - user
StudyGroup: StudyGroup:
type: object type: object
@ -1141,11 +1315,12 @@ components:
id: id:
type: integer type: integer
readOnly: true readOnly: true
users: name:
type: string
students:
type: array type: array
items: items:
type: string type: string
nullable: true
subject: subject:
type: string type: string
location: location:
@ -1153,9 +1328,9 @@ components:
landmark: landmark:
type: string type: string
nullable: true nullable: true
name: radius:
type: string type: number
maxLength: 48 format: double
active: active:
type: boolean type: boolean
timestamp: timestamp:
@ -1166,9 +1341,11 @@ components:
- id - id
- location - location
- name - name
- radius
- students
- subject - subject
- timestamp - timestamp
Subject: SubjectInstance:
type: object type: object
properties: properties:
id: id:
@ -1176,7 +1353,7 @@ components:
readOnly: true readOnly: true
name: name:
type: string type: string
maxLength: 64 readOnly: true
code: code:
type: string type: string
maxLength: 16 maxLength: 16

View file

@ -1,4 +1,4 @@
# Generated by Django 4.2.3 on 2023-09-03 09:32 # Generated by Django 4.2.3 on 2023-09-25 13:07
from django.db import migrations, models from django.db import migrations, models

View file

@ -1,4 +1,4 @@
# Generated by Django 4.2.3 on 2023-09-03 09:32 # Generated by Django 4.2.3 on 2023-09-25 13:07
from django.conf import settings from django.conf import settings
import django.contrib.gis.db.models.fields import django.contrib.gis.db.models.fields
@ -11,8 +11,10 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('accounts', '0001_initial'),
('study_groups', '0001_initial'),
('landmarks', '0001_initial'), ('landmarks', '0001_initial'),
('accounts', '0002_initial'), ('subjects', '0001_initial'),
] ]
operations = [ operations = [
@ -24,6 +26,8 @@ class Migration(migrations.Migration):
('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(null=True, on_delete=django.db.models.deletion.SET_NULL, to='landmarks.landmark')), ('landmark', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='landmarks.landmark')),
('study_group', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='students', to='study_groups.studygroup')),
('subject', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='subjects.subject', to_field='name')),
], ],
), ),
] ]

View file

@ -1,28 +0,0 @@
# Generated by Django 4.2.3 on 2023-09-03 09:32
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
('student_status', '0001_initial'),
('study_groups', '0001_initial'),
('subjects', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='studentstatus',
name='study_group',
field=models.ManyToManyField(blank=True, through='study_groups.StudyGroupMembership', to='study_groups.studygroup'),
),
migrations.AddField(
model_name='studentstatus',
name='subject',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='subjects.subject'),
),
]

View file

@ -1,20 +0,0 @@
# 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

@ -16,8 +16,8 @@ class StudentStatus(models.Model):
timestamp = models.DateTimeField(auto_now_add=True) timestamp = models.DateTimeField(auto_now_add=True)
landmark = models.ForeignKey( landmark = models.ForeignKey(
'landmarks.Landmark', on_delete=models.SET_NULL, null=True) 'landmarks.Landmark', on_delete=models.SET_NULL, null=True)
study_group = models.ManyToManyField( study_group = models.ForeignKey(
'study_groups.StudyGroup', through='study_groups.StudyGroupMembership', blank=True) 'study_groups.StudyGroup', on_delete=models.SET_NULL, null=True, related_name='students')
def __str__(self): def __str__(self):
return self.user.full_name return self.user.full_name

View file

@ -1,7 +1,6 @@
from django.contrib import admin from django.contrib import admin
from .models import StudyGroup, StudyGroupMembership from .models import StudyGroup
from leaflet.admin import LeafletGeoAdmin from leaflet.admin import LeafletGeoAdmin
admin.site.register(StudyGroup, LeafletGeoAdmin) admin.site.register(StudyGroup, LeafletGeoAdmin)
admin.site.register(StudyGroupMembership)

View file

@ -1,4 +1,4 @@
# Generated by Django 4.2.3 on 2023-09-03 09:32 # Generated by Django 4.2.3 on 2023-09-25 13:07
import django.contrib.gis.db.models.fields import django.contrib.gis.db.models.fields
from django.db import migrations, models from django.db import migrations, models
@ -10,8 +10,8 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('student_status', '0001_initial'),
('subjects', '0001_initial'), ('subjects', '0001_initial'),
('landmarks', '0001_initial'),
] ]
operations = [ operations = [
@ -23,20 +23,8 @@ class Migration(migrations.Migration):
('location', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326)), ('location', django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326)),
('active', models.BooleanField(default=False)), ('active', models.BooleanField(default=False)),
('timestamp', models.DateField(auto_now_add=True)), ('timestamp', models.DateField(auto_now_add=True)),
('landmark', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='landmarks.landmark')),
('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='subjects.subject')), ('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='subjects.subject')),
], ],
), ),
migrations.CreateModel(
name='StudyGroupMembership',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('study_group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='study_groups.studygroup')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='student_status.studentstatus')),
],
),
migrations.AddField(
model_name='studygroup',
name='users',
field=models.ManyToManyField(through='study_groups.StudyGroupMembership', to='student_status.studentstatus'),
),
] ]

View file

@ -1,20 +0,0 @@
# Generated by Django 4.2.3 on 2023-09-24 10:59
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('landmarks', '0001_initial'),
('study_groups', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='studygroup',
name='landmark',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='landmarks.landmark'),
),
]

View file

@ -7,8 +7,6 @@ from django.contrib.gis.geos import Point
class StudyGroup(models.Model): class StudyGroup(models.Model):
name = models.CharField(max_length=48) name = models.CharField(max_length=48)
users = models.ManyToManyField(
'student_status.StudentStatus', through='StudyGroupMembership')
location = gis_models.PointField(blank=True, null=True, srid=4326) location = gis_models.PointField(blank=True, null=True, srid=4326)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE) subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
active = models.BooleanField(default=False) active = models.BooleanField(default=False)
@ -18,13 +16,3 @@ class StudyGroup(models.Model):
def __str__(self): def __str__(self):
return self.name return self.name
class StudyGroupMembership(models.Model):
user = models.ForeignKey(
'student_status.StudentStatus', on_delete=models.CASCADE)
study_group = models.ForeignKey(
'study_groups.StudyGroup', on_delete=models.CASCADE)
def __str__(self):
return f'StudyGroupMembership: User={self.user}, StudyGroup={self.study_group.name}'

View file

@ -1,5 +1,5 @@
from rest_framework import serializers from rest_framework import serializers
from .models import StudyGroup, StudyGroupMembership from .models import StudyGroup
from accounts.models import CustomUser from accounts.models import CustomUser
from subjects.models import Subject from subjects.models import Subject
from drf_extra_fields.geo_fields import PointField from drf_extra_fields.geo_fields import PointField
@ -15,8 +15,7 @@ class CustomUserKeyRelatedField(serializers.PrimaryKeyRelatedField):
class StudyGroupSerializer(serializers.ModelSerializer): class StudyGroupSerializer(serializers.ModelSerializer):
name = serializers.CharField() name = serializers.CharField()
users = CustomUserKeyRelatedField( students = serializers.StringRelatedField(many=True)
queryset=CustomUser.objects.all(), many=True)
subject = serializers.SlugRelatedField( subject = serializers.SlugRelatedField(
many=False, slug_field='name', queryset=Subject.objects.all(), required=True, allow_null=False) many=False, slug_field='name', queryset=Subject.objects.all(), required=True, allow_null=False)
location = PointField() location = PointField()
@ -42,14 +41,4 @@ class StudyGroupSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = StudyGroup model = StudyGroup
fields = '__all__' fields = '__all__'
read_only_fields = ['landmark', 'radius'] read_only_fields = ['landmark', 'radius', 'students']
class StudyGroupMembershipSerializer(serializers.ModelSerializer):
user = serializers.CharField(source='accounts.CustomUser', read_only=True)
subject = serializers.CharField(
source='study_groups.StudyGroup', read_only=True)
class Meta:
model = StudyGroupMembership
fields = '__all__'

View file

@ -1,8 +1,7 @@
from django.urls import include, path from django.urls import include, path
from .views import StudyGroupListView, StudyGroupListNearView, StudyGroupMembershipViewSet from .views import StudyGroupListView, StudyGroupListNearView
urlpatterns = [ urlpatterns = [
path('', StudyGroupListView.as_view()), path('', StudyGroupListView.as_view()),
path('near/', StudyGroupListNearView.as_view()), path('near/', StudyGroupListNearView.as_view()),
path('membership/', StudyGroupMembershipViewSet.as_view()),
] ]

View file

@ -1,5 +1,5 @@
from django.shortcuts import render from django.shortcuts import render
from rest_framework import generics from rest_framework import generics, mixins
from rest_framework.exceptions import PermissionDenied from rest_framework.exceptions import PermissionDenied
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from .serializers import StudyGroupSerializer from .serializers import StudyGroupSerializer
@ -11,6 +11,8 @@ from django.contrib.gis.geos import fromstr
from django.contrib.gis.db.models.functions import Distance from django.contrib.gis.db.models.functions import Distance
from rest_framework import status from rest_framework import status
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import permissions
# Create your views here. # Create your views here.
@ -19,45 +21,6 @@ class StudyGroupListView(generics.ListCreateAPIView, generics.UpdateAPIView, gen
serializer_class = StudyGroupSerializer serializer_class = StudyGroupSerializer
queryset = StudyGroup.objects.all() queryset = StudyGroup.objects.all()
def partial_update(self, instance, request, *args, **kwargs):
# Ensure only "users" field is being updated
if set(request.data.keys()) != {"users"}:
return Response({"detail": "Only the 'users' field can be updated."}, status=status.HTTP_400_BAD_REQUEST)
# Get the current list of users
instance = self.get_object()
current_users = set(instance.users.values_list('id', flat=True))
# Get the new list of users from the request
new_users = set(request.data['users'])
# Check if the only difference between the two sets is the current user
diff = current_users.symmetric_difference(new_users)
if len(diff) > 1 or (len(diff) == 1 and request.user.id not in diff):
return Response({"detail": "You can only add or remove yourself from the study group."}, status=status.HTTP_400_BAD_REQUEST)
# Delete the study group if there are no users left
instance = self.get_object()
if not instance.users.exists():
instance.delete()
return super().partial_update(request, *args, **kwargs)
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
# Check if the current user is the creator of the study group
# Assuming 'date_joined' is a field in your User model
creator = instance.users.all().first()
if request.user != creator:
return Response({"detail": "Only the creator can delete the study group."}, status=status.HTTP_400_BAD_REQUEST)
# Check if the current user is the only one in the study group
if instance.users.count() > 1:
return Response({"detail": "The study group cannot be deleted if there are other users in it."}, status=status.HTTP_400_BAD_REQUEST)
return super().destroy(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
user = self.request.user user = self.request.user
@ -145,6 +108,7 @@ class StudyGroupListNearView(generics.ListAPIView):
return studygroups return studygroups
class StudyGroupMembershipViewSet(generics.ListAPIView): class IsOwnerOrReadOnly(permissions.BasePermission):
serializer_class = StudyGroupSerializer def has_object_permission(self, request, view, obj):
queryset = StudyGroup.objects.all() # Check if the requesting user's student status matches the user field
return obj.user == request.user.studentstatus

View file

@ -1,4 +1,4 @@
# Generated by Django 4.2.3 on 2023-09-03 09:32 # Generated by Django 4.2.3 on 2023-09-25 13:07
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models

View file

@ -3,7 +3,7 @@ from rest_framework import routers
from . import views from . import views
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register(r'group_messages', views.MessageViewSet, router.register(r'', views.MessageViewSet,
basename='group_messages') basename='group_messages')
# Wire up our API using automatic URL routing. # Wire up our API using automatic URL routing.

View file

@ -5,7 +5,6 @@ from rest_framework.permissions import IsAuthenticated
from rest_framework.exceptions import PermissionDenied from rest_framework.exceptions import PermissionDenied
from rest_framework import viewsets from rest_framework import viewsets
from student_status.models import StudentStatus from student_status.models import StudentStatus
from study_groups.models import StudyGroupMembership
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework import status from rest_framework import status
# Create your views here. # Create your views here.
@ -15,25 +14,29 @@ class MessageViewSet(viewsets.ModelViewSet):
serializer_class = MessageSerializer serializer_class = MessageSerializer
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
http_method_names = ['get', 'post'] http_method_names = ['get', 'post']
queryset = Message.objects.all()
def get_object(self):
user = self.request.user
return Message.objects.get(user=user)
def perform_create(self, serializer): def perform_create(self, serializer):
user = self.request.user user = self.request.user
study_group_id_list = StudyGroupMembership.objects.filter( user_status = StudentStatus.objects.filter(user=user).first()
user=user.id).values_list('study_group', flat=True).first() user_study_group = user_status.study_group
serializer.save(user=user, study_group_id=study_group_id_list) serializer.save(user=user, study_group=user_study_group)
def get_queryset(self): def get_queryset(self):
user = self.request.user user = self.request.user
user_status = StudentStatus.objects.filter(user=user).first()
user_study_group = user_status.study_group
if not user.is_student: if not user.is_student:
raise PermissionDenied( raise PermissionDenied(
"You must be a student to view messages of your current study group" "You must be a student to view messages of your current study group"
) )
if not user_study_group:
raise PermissionDenied(
"You are currently do not have a study group"
)
# Get student_status id of the current user # Get student_status id of the current user
student_status = StudentStatus.objects.filter( student_status = StudentStatus.objects.filter(
user=user.id user=user.id
@ -41,15 +44,9 @@ class MessageViewSet(viewsets.ModelViewSet):
print("User ID:", user.id) print("User ID:", user.id)
print("Student_Status ID:", student_status) print("Student_Status ID:", student_status)
print("User Study Group:", user_study_group)
# Get the study group id
print(StudyGroupMembership.objects.all())
study_group_id_list = StudyGroupMembership.objects.filter(
user=user.id).values_list('study_group').first()
print("Study Group List:", study_group_id_list)
# Now fetch the Messages matching the study group id # Now fetch the Messages matching the study group id
messages = Message.objects.filter( messages = Message.objects.filter(
study_group=study_group_id_list).order_by('-timestamp') study_group=user_study_group).order_by('-timestamp')
return messages return messages

View file

@ -1,4 +1,4 @@
# Generated by Django 4.2.3 on 2023-09-03 09:32 # Generated by Django 4.2.3 on 2023-09-25 13:07
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
@ -12,8 +12,8 @@ class Migration(migrations.Migration):
dependencies = [ dependencies = [
('year_levels', '0001_initial'), ('year_levels', '0001_initial'),
('semesters', '0001_initial'), ('semesters', '0001_initial'),
('courses', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL), migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('courses', '0001_initial'),
] ]
operations = [ operations = [
@ -21,7 +21,7 @@ class Migration(migrations.Migration):
name='Subject', name='Subject',
fields=[ fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=64)), ('name', models.CharField(max_length=64, unique=True)),
('students', models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL)), ('students', models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL)),
], ],
), ),
@ -32,7 +32,7 @@ class Migration(migrations.Migration):
('code', models.CharField(max_length=16)), ('code', models.CharField(max_length=16)),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.course')), ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='courses.course')),
('semester', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='semesters.semester')), ('semester', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='semesters.semester')),
('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='subjects.subject')), ('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='subjects.subject', to_field='name')),
('year_level', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='year_levels.year_level')), ('year_level', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='year_levels.year_level')),
], ],
), ),

View file

@ -1,24 +0,0 @@
# 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

@ -1,4 +1,4 @@
# Generated by Django 4.2.3 on 2023-09-03 09:32 # Generated by Django 4.2.3 on 2023-09-25 13:07
from django.db import migrations, models from django.db import migrations, models