def courses(self, request, pk): # pylint: disable=W0613 """ Returns list of courses in an organization """ organization = self.get_object() enrollment_qs = CourseEnrollment.objects\ .filter(user__organizations=organization, is_active=True)\ .values_list('course_id', 'user_id') enrollments = {} course_ids = [] for (course_id, user_id) in enrollment_qs: enrollments.setdefault(course_id, []).append(user_id) if course_id not in course_ids: course_ids.append(course_id) course_keys = map(get_course_key, filter(None, course_ids)) if request.query_params.get('mobile_available'): mobile_available = str2bool(request.query_params.get('mobile_available')) courses = CourseOverview.objects.filter(id__in=course_keys, mobile_available=mobile_available) else: courses = CourseOverview.objects.filter(id__in=course_keys) serializer = OrganizationCourseSerializer(courses, many=True, context={'request': request, 'enrollments': enrollments}) return Response(serializer.data, status=status.HTTP_200_OK)
def get(self, request, group_id): """ GET /api/groups/{group_id}/users/ """ try: existing_group = Group.objects.get(id=group_id) except ObjectDoesNotExist: return Response({}, status.HTTP_404_NOT_FOUND) users = existing_group.user_set.all() is_active = request.query_params.get('is_active', None) if is_active: users = users.filter(is_active=str2bool(is_active)) response_data = {} response_data['users'] = [] for user in users: user_data = {} user_data['id'] = user.id user_data['email'] = user.email user_data['username'] = user.username user_data['first_name'] = user.first_name user_data['last_name'] = user.last_name response_data['users'].append(user_data) response_status = status.HTTP_200_OK return Response(response_data, status=response_status)
def courses(self, request, pk): # pylint: disable=W0613 """ Returns list of courses in an organization """ organization = self.get_object() enrollment_qs = CourseEnrollment.objects\ .filter(user__organizations=organization, is_active=True)\ .values_list('course_id', 'user_id') enrollments = {} course_ids = [] for (course_id, user_id) in enrollment_qs: enrollments.setdefault(course_id, []).append(user_id) if course_id not in course_ids: course_ids.append(course_id) course_keys = map(get_course_key, filter(None, course_ids)) if request.query_params.get('mobile_available'): mobile_available = str2bool( request.query_params.get('mobile_available')) courses = CourseOverview.objects.filter( id__in=course_keys, mobile_available=mobile_available) else: courses = CourseOverview.objects.filter(id__in=course_keys) serializer = OrganizationCourseSerializer(courses, many=True, context={ 'request': request, 'enrollments': enrollments }) return Response(serializer.data, status=status.HTTP_200_OK)
def courses(self, request, pk): # pylint: disable=W0613 """ Returns list of courses in an organization """ exclude_admins = str2bool(request.query_params.get('exclude_admins')) organization = self.get_object() organization_courses = [] organization_course_ids = [] roles_to_exclude = [] if exclude_admins: organization_courses = CourseEnrollment.objects\ .filter(user__organizations=organization, is_active=True)\ .order_by('course_id').distinct().values_list('course_id', flat=True) for course_id in organization_courses: organization_course_ids.append(course_id.to_deprecated_string()) organization_courses = map(get_course_key, filter(None, organization_course_ids)) roles_to_exclude = [CourseInstructorRole.ROLE, CourseStaffRole.ROLE, CourseObserverRole.ROLE, CourseAssistantRole.ROLE] enrollment_qs = CourseEnrollment.objects\ .filter(user__organizations=organization, is_active=True)\ .exclude( user_id__in=CourseAccessRole.objects.filter( course_id__in=organization_courses, role__in=roles_to_exclude ).values_list('user_id', flat=True) ).values_list('course_id', 'user_id') enrollments = {} course_ids = [] for (course_id, user_id) in enrollment_qs: enrollments.setdefault(course_id.to_deprecated_string(), []).append(user_id) if course_id.to_deprecated_string() not in course_ids: course_ids.append(course_id.to_deprecated_string()) course_keys = map(get_course_key, filter(None, course_ids)) if request.query_params.get('mobile_available'): mobile_available = str2bool(request.query_params.get('mobile_available')) courses = CourseOverview.objects.filter(id__in=course_keys, mobile_available=mobile_available) else: courses = CourseOverview.objects.filter(id__in=course_keys) serializer = OrganizationCourseSerializer(courses, many=True, context={'request': request, 'enrollments': enrollments}) return Response(serializer.data, status=status.HTTP_200_OK)
def filter_queryset(self, request, queryset, view): """ Parse querystring base on has_organizations query param """ has_orgs = request.QUERY_PARAMS.get('has_organizations', None) if has_orgs: if str2bool(has_orgs): queryset = queryset.filter(organizations__id__gt=0) else: queryset = queryset.exclude(id__in=User.objects.filter( organizations__id__gt=0).values_list('id', flat=True)) return queryset.distinct()
def users(self, request, pk): """ - URI: ```/api/organizations/{org_id}/users/``` - GET: Returns users in an organization * course_id parameter should filter user by course * include_course_counts parameter should be `true` to get user's enrollment count * include_grades parameter should be `true` to get user's grades * for the course given in the course_id parameter * view parameter can be used to get a particular data .i.e. view=ids to * get list of user ids - POST: Adds a User to an Organization - DELETE: Removes the user(s) given in the `users` param from an Organization. """ if request.method == 'GET': include_course_counts = request.query_params.get('include_course_counts', None) include_grades = request.query_params.get('include_grades', None) course_id = request.query_params.get('course_id', None) view = request.query_params.get('view', None) grade_complete_match_range = getattr(settings, 'GRADEBOOK_GRADE_COMPLETE_PROFORMA_MATCH_RANGE', 0.01) course_key = None if course_id: course_key = get_course_key(course_id) users = User.objects.filter(organizations=pk) if course_key: users = users.filter(courseenrollment__course_id__exact=course_key, courseenrollment__is_active=True) if str2bool(include_grades): users = users.prefetch_related( Prefetch('studentgradebook_set', queryset=StudentGradebook.objects.filter(course_id=course_key)) ) if str2bool(include_course_counts): enrollments = CourseEnrollment.objects.filter(user__in=users).values('user').order_by().annotate(total=Count('user')) enrollments_by_user = {} for enrollment in enrollments: enrollments_by_user[enrollment['user']] = enrollment['total'] # if we only need ids of users in organization return now if view == 'ids': user_ids = users.values_list('id', flat=True) return Response(user_ids) response_data = [] if users: for user in users: serializer = SimpleUserSerializer(user) user_data = serializer.data if str2bool(include_course_counts): user_data['course_count'] = enrollments_by_user.get(user.id, 0) if str2bool(include_grades) and course_key: user_grades = {'grade': 0, 'proforma_grade': 0, 'complete_status': False} gradebook = user.studentgradebook_set.all() if gradebook: user_grades['grade'] = gradebook[0].grade user_grades['proforma_grade'] = gradebook[0].proforma_grade user_grades['complete_status'] = True if 0 < gradebook[0].proforma_grade <= \ gradebook[0].grade + grade_complete_match_range else False user_data.update(user_grades) response_data.append(user_data) return Response(response_data, status=status.HTTP_200_OK) elif request.method == 'DELETE': user_ids = request.data.get('users') if not user_ids: return Response({"detail": _('users parameter is missing.')}, status.HTTP_400_BAD_REQUEST) try: user_ids = [int(user_id) for user_id in filter(None, user_ids.split(','))] except (ValueError, AttributeError): return Response({ "detail": _('users parameter must be comma separated list of integers.') }, status.HTTP_400_BAD_REQUEST) organization = self.get_object() users_to_be_deleted = organization.users.filter(id__in=user_ids) total_users = len(users_to_be_deleted) if total_users > 0: organization.users.remove(*users_to_be_deleted) return Response({ "detail": _("{users_removed} user(s) removed from organization").format(users_removed=total_users) }, status=status.HTTP_200_OK) else: return Response(status=status.HTTP_204_NO_CONTENT) else: user_id = request.data.get('id') try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = 'User {} does not exist'.format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) organization = self.get_object() organization.users.add(user) organization.save() return Response({}, status=status.HTTP_201_CREATED)
def users(self, request, pk): """ - URI: ```/api/organizations/{org_id}/users/``` - GET: Returns users in an organization * course_id parameter should filter user by course * include_course_counts parameter should be `true` to get user's enrollment count * include_grades parameter should be `true` to get user's grades * for the course given in the course_id parameter * view parameter can be used to get a particular data .i.e. view=ids to * get list of user ids - POST: Adds a User to an Organization - DELETE: Removes the user(s) given in the `users` param from an Organization. """ if request.method == 'GET': include_course_counts = request.query_params.get( 'include_course_counts', None) include_grades = request.query_params.get('include_grades', None) course_id = request.query_params.get('course_id', None) view = request.query_params.get('view', None) grade_complete_match_range = getattr( settings, 'GRADEBOOK_GRADE_COMPLETE_PROFORMA_MATCH_RANGE', 0.01) course_key = None if course_id: course_key = get_course_key(course_id) users = User.objects.filter(organizations=pk) if course_key: users = users.filter( courseenrollment__course_id__exact=course_key, courseenrollment__is_active=True) if str2bool(include_grades): users = users.prefetch_related('studentgradebook_set') if str2bool(include_course_counts): enrollments = CourseEnrollment.objects.filter( user__in=users).values('user').order_by().annotate( total=Count('user')) enrollments_by_user = {} for enrollment in enrollments: enrollments_by_user[ enrollment['user']] = enrollment['total'] # if we only need ids of users in organization return now if view == 'ids': user_ids = users.values_list('id', flat=True) return Response(user_ids) response_data = [] if users: for user in users: serializer = SimpleUserSerializer(user) user_data = serializer.data if str2bool(include_course_counts): user_data['course_count'] = enrollments_by_user.get( user.id, 0) if str2bool(include_grades) and course_key: user_grades = { 'grade': 0, 'proforma_grade': 0, 'complete_status': False } gradebook = user.studentgradebook_set.filter( course_id=course_key) if gradebook: user_grades['grade'] = gradebook[0].grade user_grades['proforma_grade'] = gradebook[ 0].proforma_grade user_grades['complete_status'] = True if 0 < gradebook[0].proforma_grade <= \ gradebook[0].grade + grade_complete_match_range else False user_data.update(user_grades) response_data.append(user_data) return Response(response_data, status=status.HTTP_200_OK) elif request.method == 'DELETE': user_ids = request.data.get('users') if not user_ids: return Response({"detail": _('users parameter is missing.')}, status.HTTP_400_BAD_REQUEST) try: user_ids = [ int(user_id) for user_id in filter(None, user_ids.split(',')) ] except (ValueError, AttributeError): return Response( { "detail": _('users parameter must be comma separated list of integers.' ) }, status.HTTP_400_BAD_REQUEST) organization = self.get_object() users_to_be_deleted = organization.users.filter(id__in=user_ids) total_users = len(users_to_be_deleted) for user in users_to_be_deleted: organization.users.remove(user) if total_users > 0: return Response( { "detail": _("{users_removed} user(s) removed from organization"). format(users_removed=total_users) }, status=status.HTTP_200_OK) else: return Response(status=status.HTTP_204_NO_CONTENT) else: user_id = request.data.get('id') try: user = User.objects.get(id=user_id) except ObjectDoesNotExist: message = 'User {} does not exist'.format(user_id) return Response({"detail": message}, status.HTTP_400_BAD_REQUEST) organization = self.get_object() organization.users.add(user) organization.save() return Response({}, status=status.HTTP_201_CREATED)