Skip to content

Commit 7039be3

Browse files
authored
Merge pull request #24 from DevOps-Cloud-Team5/SCRUM-90-Course-info
course page + attendence stats
2 parents 1b81cbc + c391044 commit 7039be3

File tree

4 files changed

+59
-6
lines changed

4 files changed

+59
-6
lines changed

api/models.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ def __str__(self):
6868
return str(self.name)
6969

7070
def get_enrolled_students(self):
71-
return [uc.user for uc in UserCourse.objects.filter(user__role=AccountRoles.STUDENT)]
71+
return [uc.user for uc in UserCourse.objects.filter(user__role=AccountRoles.STUDENT, course=self)]
7272

7373
def get_teachers(self):
74-
return [uc.user for uc in UserCourse.objects.filter(user__role=AccountRoles.TEACHER)]
74+
return [uc.user for uc in UserCourse.objects.filter(user__role=AccountRoles.TEACHER, course=self)]
7575

7676
def get_lectures(self):
7777
return CourseLecture.objects.filter(course=self)

api/serializers.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ class UserSerializer(serializers.ModelSerializer):
2424
class Meta:
2525
model = User
2626
fields = '__all__'
27-
27+
28+
class CourseUserSerializer(serializers.ModelSerializer):
29+
class Meta:
30+
model = User
31+
fields = ["username", "first_name", "last_name", "role"]
32+
2833
class CourseSerializer(serializers.ModelSerializer):
2934
class Meta:
3035
model = Course

api/urls.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from .views import (
2121
AddLectureView,
2222
GetCourseLecturesView,
23+
GetFullCoursePage,
2324
GetLectureView,
2425
GetScheduleView,
2526
MassEnrollCourseView,
@@ -75,9 +76,10 @@
7576
path('course/delete/<pk>', DestroyCourseView.as_view(), name='course_delete'),
7677
path('course/enroll/<pk>', EnrollCourseView.as_view(), name='course_enroll'),
7778
path('course/mass_enroll/<pk>', MassEnrollCourseView.as_view(), name='course_mass_enroll'),
78-
path('course/get/<pk>', GetCourseByName.as_view(), name='course_get'),
79+
path('course/get/<pk>', GetFullCoursePage.as_view(), name='course_get'),
7980
path('course/getall/', GetCoursesAll.as_view(), name='course_getall'),
8081

82+
8183
path('course/lecture/<pk>/get', GetCourseLecturesView.as_view(), name='course_get_lecture'),
8284
path('course/lecture/<pk>/add', AddLectureView.as_view(), name='course_add_lecture'),
8385
# path('course/lecture/<pk>/update', GetCourseByName.as_view(), name='lecture_add'), # TODO

api/views.py

+48-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616

1717
from .permissions import IsTeacher, IsAdmin, IsStudent
1818
from .models import Course, AccountRoles, CourseLecture
19-
from .serializers import AddLectureSerializer, CustomTokenSerializer, CreateUserSerializer, LectureSerializer, MassEnrollSerializer, SetAttendenceTeacherSerializer, UserSerializer, CourseCreateSerializer, CourseSerializer, MailTestSerializer
19+
20+
from .serializers import AddLectureSerializer, CourseUserSerializer, CustomTokenSerializer, CreateUserSerializer, LectureSerializer, MassEnrollSerializer, SetAttendenceTeacherSerializer, UserSerializer, CourseCreateSerializer, CourseSerializer
21+
22+
2023

2124
from django.core.mail import send_mail
2225

@@ -216,6 +219,48 @@ def get(self, _, pk):
216219
serializer = self.serializer_class(queryset[0])
217220
return Response(serializer.data, status=status.HTTP_200_OK)
218221

222+
class GetFullCoursePage(generics.RetrieveAPIView):
223+
authentication_classes = [JWTAuthentication]
224+
permission_classes = [IsStudent]
225+
226+
queryset = Course.objects.all()
227+
serializer_class = CourseSerializer
228+
229+
def get_attendence_stats(self, course, user):
230+
lectures : List[CourseLecture] = course.get_lectures()
231+
attendence_stats = {"attended": 0, "missed": 0}
232+
for lecture in lectures:
233+
if lecture.end_time > datetime.datetime.now(lecture.end_time.tzinfo): continue
234+
att = lecture.get_attendence_user(user)
235+
if att is None or not (att.attended_student and att.attended_teacher):
236+
attendence_stats["missed"] += 1
237+
else: attendence_stats["attended"] += 1
238+
return attendence_stats
239+
240+
def get(self, request, pk):
241+
queryset = self.get_queryset().filter(pk=pk)
242+
if not queryset:
243+
return Response({"error": f"course id '{pk}' not found"}, status=status.HTTP_404_NOT_FOUND)
244+
245+
course : Course = queryset[0]
246+
teachers = course.get_teachers()
247+
students = course.get_enrolled_students()
248+
249+
response_data = {}
250+
response_data["id"] = pk
251+
response_data["course_name"] = course.course_name
252+
response_data["num_teachers"] = len(teachers)
253+
response_data["num_students"] = len(students)
254+
response_data["attended"] = -1
255+
response_data["missed"] = -1
256+
response_data["users"] = CourseUserSerializer((teachers + students), many=True).data
257+
258+
user = User.objects.all().filter(username=request.user.username)[0]
259+
if user.role == AccountRoles.STUDENT:
260+
response_data |= self.get_attendence_stats(course, user)
261+
262+
return Response(response_data, status=status.HTTP_200_OK)
263+
219264
class GetCoursesAll(generics.ListAPIView):
220265
authentication_classes = [JWTAuthentication]
221266
permission_classes = [IsStudent]
@@ -413,4 +458,5 @@ def get(self, request, year, week):
413458
# Sort chronological order
414459
all_lectures.sort(key= lambda x : datetime.datetime.fromisoformat(x["start_time"]))
415460

416-
return Response(all_lectures)
461+
return Response(all_lectures, status=status.HTTP_200_OK)
462+

0 commit comments

Comments
 (0)