Commit c907daa4 by Zia Fazal Committed by Jonathan Piacenti

New API to get users

Added new API to get enrolled and not enrolled users in Course Content
Group: MCKIN-1027

Also contains:

* Changes base on Matt's Feedback
* Further changes based on Matt's feedback
parent 508dfa68
......@@ -38,6 +38,7 @@ class CoursesApiTests(TestCase):
self.test_server_prefix = 'https://testserver'
self.base_courses_uri = '/api/courses'
self.base_groups_uri = '/api/groups'
self.base_users_uri = '/api/users'
self.test_group_name = 'Alpha Group'
self.course = CourseFactory.create()
......@@ -1028,3 +1029,75 @@ class CoursesApiTests(TestCase):
)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 404)
def test_course_content_users_list_get(self):
test_uri = '{}/{}/groups'.format(self.base_course_content_uri, self.course_project.id)
test_uri_users = '{}/{}/users'.format(self.base_course_content_uri, self.course_project.id)
test_course_users_uri = self.base_courses_uri + '/' + self.test_course_id + '/users'
# Create a group and add it to course module
data = {'name': 'Alpha Group', 'type': 'test'}
response = self.do_post(self.base_groups_uri, data)
self.assertEqual(response.status_code, 201)
group_id = response.data['id']
data = {'group_id': group_id}
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 201)
# Create another group and add it to course module
data = {'name': 'Beta Group', 'type': 'project'}
response = self.do_post(self.base_groups_uri, data)
self.assertEqual(response.status_code, 201)
another_group_id = response.data['id']
data = {'group_id': another_group_id}
response = self.do_post(test_uri, data)
self.assertEqual(response.status_code, 201)
# create a 5 new users
for i in xrange(1, 6):
data = {
'email': 'test{}@example.com'.format(i),
'username': 'test_user{}'.format(i),
'password': 'test_pass',
'first_name': 'John{}'.format(i),
'last_name': 'Doe{}'.format(i)
}
response = self.do_post(self.base_users_uri, data)
self.assertEqual(response.status_code, 201)
created_user_id = response.data['id']
#add two users to Alpha Group and one to Beta Group and keep two without any group
if i <= 3:
add_to_group = group_id
if i > 2:
add_to_group = another_group_id
test_group_users_uri = '{}/{}/users'.format(self.base_groups_uri, add_to_group)
data = {'user_id': created_user_id}
response = self.do_post(test_group_users_uri, data)
self.assertEqual(response.status_code, 201)
#enroll one user in Alpha Group and one in Beta Group created user
if i >= 2:
response = self.do_post(test_course_users_uri, data)
self.assertEqual(response.status_code, 201)
response = self.do_get('{}?enrolled={}'.format(test_uri_users, 'True'))
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 2)
response = self.do_get('{}?enrolled={}'.format(test_uri_users, 'False'))
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)
#filter by group id
response = self.do_get('{}?enrolled={}&group_id={}'.format(test_uri_users, 'true', group_id))
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)
response = self.do_get('{}?enrolled={}&group_id={}'.format(test_uri_users, 'false', group_id))
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)
#filter by group type
response = self.do_get('{}?enrolled={}&type={}'.format(test_uri_users, 'true', 'project'))
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), 1)
......@@ -15,6 +15,7 @@ urlpatterns = patterns(
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/content/(?P<content_id>[a-zA-Z0-9/_:]+)/groups/(?P<group_id>[0-9]+)$', courses_views.CourseContentGroupsDetail.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/content/(?P<content_id>[a-zA-Z0-9/_:]+)/groups/*$', courses_views.CourseContentGroupsList.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/content/(?P<content_id>[a-zA-Z0-9/_:]+)/children/*$', courses_views.CourseContentList.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/content/(?P<content_id>[a-zA-Z0-9/_:]+)/users/*$', courses_views.CourseContentUsersList.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/content/(?P<content_id>[a-zA-Z0-9/_:]+)$', courses_views.CourseContentDetail.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/content/*$', courses_views.CourseContentList.as_view()),
url(r'^(?P<course_id>[^/]+/[^/]+/[^/]+)/groups/(?P<group_id>[0-9]+)$', courses_views.CoursesGroupsDetail.as_view()),
......
......@@ -2,6 +2,7 @@
from collections import OrderedDict
import logging
import itertools
from lxml import etree
from StringIO import StringIO
......@@ -9,12 +10,13 @@ from django.contrib.auth.models import Group, User
from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404
from rest_framework import status
from rest_framework import status, generics
from rest_framework.response import Response
from rest_framework.views import APIView
from api_manager.permissions import ApiKeyHeaderPermission
from api_manager.models import CourseGroupRelationship, CourseContentGroupRelationship, GroupProfile
from api_manager.users.serializers import UserSerializer
from courseware import module_render
from courseware.courses import get_course, get_course_about_section, get_course_info_section
from courseware.model_data import FieldDataCache
......@@ -844,3 +846,47 @@ class CourseContentGroupsDetail(APIView):
'group_id': group_id,
}
return Response(response_data, status=status.HTTP_200_OK)
class CourseContentUsersList(generics.ListAPIView):
"""
### The CourseContentUsersList view allows clients to users enrolled and
users not enrolled for course within all groups of course
- URI: ```/api/courses/{course_id}/content/{content_id}/users?enrolled={enrolment_status}&group_id={group_id}&type={group_type}```
- GET: Returns a JSON representation of users enrolled or not enrolled
### Use Cases/Notes:
* Use CourseContentUsersList to grab the users enrolled in Course content group
* Use CourseContentUsersList to grab the users not enrolled in Course content group
"""
permission_classes = (ApiKeyHeaderPermission,)
serializer_class = UserSerializer
def get_queryset(self):
"""
GET retrieves the list of users who registered for a given course content
and list of users who are not registered for that group course content.
'enrolled' query parameter for filtering user' enrolment status
'group_id' query parameter is available for filtering by group.
'type' query parameter is available for filtering by group_type.
"""
course_id = self.kwargs['course_id']
content_id = self.kwargs['content_id']
enrolled = self.request.QUERY_PARAMS.get('enrolled', 'True')
group_type = self.request.QUERY_PARAMS.get('type', None)
group_id = self.request.QUERY_PARAMS.get('group_id', None)
groups = CourseContentGroupRelationship.objects.filter(course_id=course_id, content_id=content_id)
if group_id:
groups = groups.filter(group__group__id=group_id)
if group_type:
groups = groups.filter(group__group_type=group_type)
lookup_group_ids = groups.values_list('group_id', flat=True)
users = User.objects.filter(groups__id__in=lookup_group_ids)
enrolled_users = CourseEnrollment.users_enrolled_in(course_id).filter(groups__id__in=lookup_group_ids)
if enrolled in ['True', 'true']:
queryset = enrolled_users
else:
queryset = list(itertools.ifilterfalse(lambda x: x in enrolled_users, users))
return queryset
......@@ -10,5 +10,5 @@ class UserSerializer(serializers.ModelSerializer):
class Meta:
""" Serializer/field specification """
model = User
fields = ("id", "email", "username")
fields = ("id", "email", "username", "first_name", "last_name")
read_only_fields = ("id", "email", "username")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment