diff --git a/codeforlife/user/models/__init__.py b/codeforlife/user/models/__init__.py index b7fb98e1..1cf7834a 100644 --- a/codeforlife/user/models/__init__.py +++ b/codeforlife/user/models/__init__.py @@ -1,10 +1,9 @@ -# from .classroom import Class - -# # from .other import * +# from .other import * # from .school import School # from .session import UserSession # from .teacher_invitation import SchoolTeacherInvitation from .auth_factor import AuthFactor +from .klass import Class # 'class' is a reserved keyword from .otp_bypass_token import OtpBypassToken from .session import Session from .session_auth_factor import SessionAuthFactor diff --git a/codeforlife/user/models/classroom.py b/codeforlife/user/models/classroom.py deleted file mode 100644 index a743a025..00000000 --- a/codeforlife/user/models/classroom.py +++ /dev/null @@ -1,100 +0,0 @@ -from uuid import uuid4 -from datetime import timedelta - -from django.db import models -from django.utils import timezone - -from .teacher import Teacher - - -class ClassModelManager(models.Manager): - def all_members(self, user): - members = [] - if hasattr(user, "teacher"): - members.append(user.teacher) - if user.teacher.has_school(): - classes = user.teacher.class_teacher.all() - for c in classes: - members.extend(c.students.all()) - else: - c = user.student.class_field - members.append(c.teacher) - members.extend(c.students.all()) - return members - - # Filter out non active classes by default - def get_queryset(self): - return super().get_queryset().filter(is_active=True) - - -class Class(models.Model): - name = models.CharField(max_length=200) - teacher = models.ForeignKey( - Teacher, related_name="class_teacher", on_delete=models.CASCADE - ) - access_code = models.CharField(max_length=5, null=True) - classmates_data_viewable = models.BooleanField(default=False) - always_accept_requests = models.BooleanField(default=False) - accept_requests_until = models.DateTimeField(null=True) - creation_time = models.DateTimeField(default=timezone.now, null=True) - is_active = models.BooleanField(default=True) - created_by = models.ForeignKey( - Teacher, - null=True, - blank=True, - related_name="created_classes", - on_delete=models.SET_NULL, - ) - - objects = ClassModelManager() - - def __str__(self): - return self.name - - @property - def active_game(self): - games = self.game_set.filter(game_class=self, is_archived=False) - if len(games) >= 1: - assert ( - len(games) == 1 - ) # there should NOT be more than one active game - return games[0] - return None - - def has_students(self): - students = self.students.all() - return students.count() != 0 - - def get_requests_message(self): - if self.always_accept_requests: - external_requests_message = ( - "This class is currently set to always accept requests." - ) - elif ( - self.accept_requests_until is not None - and (self.accept_requests_until - timezone.now()) >= timedelta() - ): - external_requests_message = ( - "This class is accepting external requests until " - + self.accept_requests_until.strftime("%d-%m-%Y %H:%M") - + " " - + timezone.get_current_timezone_name() - ) - else: - external_requests_message = ( - "This class is not currently accepting external requests." - ) - - return external_requests_message - - def anonymise(self): - self.name = uuid4().hex - self.access_code = "" - self.is_active = False - self.save() - - # Remove independent students' requests to join this class - self.class_request.clear() - - class Meta(object): - verbose_name_plural = "classes" diff --git a/codeforlife/user/models/klass.py b/codeforlife/user/models/klass.py new file mode 100644 index 00000000..fa7f12f7 --- /dev/null +++ b/codeforlife/user/models/klass.py @@ -0,0 +1,102 @@ +# from uuid import uuid4 +# from datetime import timedelta + +# from django.db import models +# from django.utils import timezone + +# from .teacher import Teacher + + +# class ClassModelManager(models.Manager): +# def all_members(self, user): +# members = [] +# if hasattr(user, "teacher"): +# members.append(user.teacher) +# if user.teacher.has_school(): +# classes = user.teacher.class_teacher.all() +# for c in classes: +# members.extend(c.students.all()) +# else: +# c = user.student.class_field +# members.append(c.teacher) +# members.extend(c.students.all()) +# return members + +# # Filter out non active classes by default +# def get_queryset(self): +# return super().get_queryset().filter(is_active=True) + + +# class Class(models.Model): +# name = models.CharField(max_length=200) +# teacher = models.ForeignKey( +# Teacher, related_name="class_teacher", on_delete=models.CASCADE +# ) +# access_code = models.CharField(max_length=5, null=True) +# classmates_data_viewable = models.BooleanField(default=False) +# always_accept_requests = models.BooleanField(default=False) +# accept_requests_until = models.DateTimeField(null=True) +# creation_time = models.DateTimeField(default=timezone.now, null=True) +# is_active = models.BooleanField(default=True) +# created_by = models.ForeignKey( +# Teacher, +# null=True, +# blank=True, +# related_name="created_classes", +# on_delete=models.SET_NULL, +# ) + +# objects = ClassModelManager() + +# def __str__(self): +# return self.name + +# @property +# def active_game(self): +# games = self.game_set.filter(game_class=self, is_archived=False) +# if len(games) >= 1: +# assert ( +# len(games) == 1 +# ) # there should NOT be more than one active game +# return games[0] +# return None + +# def has_students(self): +# students = self.students.all() +# return students.count() != 0 + +# def get_requests_message(self): +# if self.always_accept_requests: +# external_requests_message = ( +# "This class is currently set to always accept requests." +# ) +# elif ( +# self.accept_requests_until is not None +# and (self.accept_requests_until - timezone.now()) >= timedelta() +# ): +# external_requests_message = ( +# "This class is accepting external requests until " +# + self.accept_requests_until.strftime("%d-%m-%Y %H:%M") +# + " " +# + timezone.get_current_timezone_name() +# ) +# else: +# external_requests_message = ( +# "This class is not currently accepting external requests." +# ) + +# return external_requests_message + +# def anonymise(self): +# self.name = uuid4().hex +# self.access_code = "" +# self.is_active = False +# self.save() + +# # Remove independent students' requests to join this class +# self.class_request.clear() + +# class Meta(object): +# verbose_name_plural = "classes" + +from common.models import Class diff --git a/codeforlife/user/serializers/__init__.py b/codeforlife/user/serializers/__init__.py index 03db9d8e..98793d93 100644 --- a/codeforlife/user/serializers/__init__.py +++ b/codeforlife/user/serializers/__init__.py @@ -1,3 +1,4 @@ +from .klass import ClassSerializer from .student import StudentSerializer from .teacher import TeacherSerializer from .user import UserSerializer diff --git a/codeforlife/user/serializers/klass.py b/codeforlife/user/serializers/klass.py new file mode 100644 index 00000000..b1ac456d --- /dev/null +++ b/codeforlife/user/serializers/klass.py @@ -0,0 +1,12 @@ +from rest_framework import serializers + +from ..models import Class + + +class ClassSerializer(serializers.ModelSerializer): + class Meta: + model = Class + fields = "__all__" + extra_kwargs = { + "id": {"read_only": True}, + } diff --git a/codeforlife/user/serializers/student.py b/codeforlife/user/serializers/student.py index c9315e10..660e03f7 100644 --- a/codeforlife/user/serializers/student.py +++ b/codeforlife/user/serializers/student.py @@ -7,3 +7,6 @@ class StudentSerializer(serializers.ModelSerializer): class Meta: model = Student fields = "__all__" + extra_kwargs = { + "id": {"read_only": True}, + } diff --git a/codeforlife/user/serializers/teacher.py b/codeforlife/user/serializers/teacher.py index dacba7ed..160c63a7 100644 --- a/codeforlife/user/serializers/teacher.py +++ b/codeforlife/user/serializers/teacher.py @@ -7,3 +7,6 @@ class TeacherSerializer(serializers.ModelSerializer): class Meta: model = Teacher fields = "__all__" + extra_kwargs = { + "id": {"read_only": True}, + } diff --git a/codeforlife/user/urls.py b/codeforlife/user/urls.py index 0e184848..a9b96aed 100644 --- a/codeforlife/user/urls.py +++ b/codeforlife/user/urls.py @@ -1,9 +1,10 @@ from django.urls import include, path from rest_framework.routers import DefaultRouter -from .views import UserViewSet +from .views import ClassViewSet, UserViewSet router = DefaultRouter() +router.register("classes", ClassViewSet, basename="class") router.register("users", UserViewSet, basename="user") urlpatterns = [ diff --git a/codeforlife/user/views/__init__.py b/codeforlife/user/views/__init__.py index 409ba85d..6895d588 100644 --- a/codeforlife/user/views/__init__.py +++ b/codeforlife/user/views/__init__.py @@ -1 +1,2 @@ +from .klass import ClassViewSet from .user import UserViewSet diff --git a/codeforlife/user/views/klass.py b/codeforlife/user/views/klass.py new file mode 100644 index 00000000..e0af7c71 --- /dev/null +++ b/codeforlife/user/views/klass.py @@ -0,0 +1,18 @@ +from rest_framework.viewsets import ModelViewSet + +from ..models import Class, User +from ..serializers import ClassSerializer + + +class ClassViewSet(ModelViewSet): + serializer_class = ClassSerializer + + def get_queryset(self): + user: User = self.request.user + if user.teacher is None: + return Class.objects.filter(students=user) + elif user.teacher.is_admin: + # TODO: add school field to class object + return Class.objects.filter(teacher__school=user.teacher.school) + else: + return Class.objects.filter(teacher=user) diff --git a/codeforlife/user/views/user.py b/codeforlife/user/views/user.py index 61001cb2..247becdb 100644 --- a/codeforlife/user/views/user.py +++ b/codeforlife/user/views/user.py @@ -11,14 +11,12 @@ class UserViewSet(ModelViewSet): filterset_class = UserFilterSet def get_queryset(self): - queryset = User.objects.all() user: User = self.request.user - if user.teacher is not None: - queryset = queryset.filter( + if user.teacher is None: + return User.objects.filter(id=user.id) + else: + return User.objects.filter( new_teacher__school=user.teacher.school_id, # TODO: add school foreign key to student model. - new_student__class_field__created_by__school=user.teacher.school_id, + new_student__class_field__teacher__school=user.teacher.school_id, ) - else: - queryset = queryset.filter(id=user.id) - return queryset