def course_view_data(request, slug) -> Tuple[Optional[CourseInstance], Optional[Dict]]: """Retrieves course and relevant data for the request. If course does not exist it returns two None objects. """ course: CourseInstance = None try: course = CourseInstance.objects.filter(slug=slug).select_related( 'semester', 'course_type').prefetch_related('tags', 'effects').get() except CourseInstance.DoesNotExist: return None, None student: Student = None if request.user.is_authenticated and request.user.student: student = request.user.student groups = course.groups.exclude(extra='hidden').select_related( 'teacher', 'teacher__user', ).prefetch_related('term', 'term__classrooms', 'guaranteed_spots', 'guaranteed_spots__role') # Collect the general groups statistics. groups_stats = Record.groups_stats(groups) # Collect groups information related to the student. student_status_groups = Record.is_recorded_in_groups(student, groups) student_can_enqueue = Record.can_enqueue_groups(student, course.groups.all()) student_can_dequeue = Record.can_dequeue_groups(student, course.groups.all()) for group in groups: group.num_enrolled = groups_stats.get(group.pk).get('num_enrolled') group.num_enqueued = groups_stats.get(group.pk).get('num_enqueued') group.is_enrolled = student_status_groups.get(group.pk).get('enrolled') group.is_enqueued = student_status_groups.get(group.pk).get('enqueued') group.priority = student_status_groups.get(group.pk).get('priority') group.can_enqueue = student_can_enqueue.get(group.pk) group.can_dequeue = student_can_dequeue.get(group.pk) teachers = {g.teacher for g in groups} course.is_enrollment_on = any(g.can_enqueue for g in groups) waiting_students = {} if request.user.employee: waiting_students = Record.list_waiting_students([course])[course.id] data = { 'course': course, 'teachers': teachers, 'groups': groups, 'waiting_students': waiting_students, } return course, data
def build_group_list(groups: List[Group]): """Builds a serializable object containing relevant information about groups The information must be sufficient to display information in the timetable and perform actions (enqueuing/dequeuing). """ stats = Record.groups_stats(groups) group_dicts = [] group: Group for group in groups: group_dict = model_to_dict(group, fields=['id', 'limit', 'extra']) term_dicts = [] for term in group.term.all(): term_dict = model_to_dict(term, fields=['dayOfWeek', 'start_time', 'end_time']) term_dict['classrooms'] = term.numbers() term_dicts.append(term_dict) guaranteed_spots = [{ 'role': gs.role.name, 'limit': gs.limit, } for gs in group.guaranteed_spots.all()] group_dict.update({ 'course': { 'url': reverse('course-page', args=(group.course.slug, )), 'name': group.course.name, 'shortName': group.course.short_name, }, 'type': decode_class_type_singular(group.type), 'url': reverse('group-view', args=(group.pk, )), 'teacher': { 'id': group.teacher_id, 'url': reverse('employee-profile', args=(group.teacher.user_id, )), 'name': group.teacher.user.get_full_name(), }, 'num_enrolled': stats.get(group.pk).get('num_enrolled'), 'term': term_dicts, 'guaranteed_spots': guaranteed_spots, 'is_enrolled': getattr(group, 'is_enrolled', None), 'is_enqueued': getattr(group, 'is_enqueued', None), 'is_pinned': getattr(group, 'is_pinned', None), 'can_enqueue': getattr(group, 'can_enqueue', None), 'can_dequeue': getattr(group, 'can_dequeue', None), 'action_url': reverse('prototype-action', args=(group.pk, )), }) group_dicts.append(group_dict) return group_dicts