Commit 99c64d62 by Zia Fazal Committed by Jonathan Piacenti

ziafazal/api-course-detail-for-multiple-courses: added filter

in courses list to get courses by id
parent fd4963c5
...@@ -55,11 +55,13 @@ class CourseCompletionsLeadersSerializer(serializers.Serializer): ...@@ -55,11 +55,13 @@ class CourseCompletionsLeadersSerializer(serializers.Serializer):
class CourseSerializer(serializers.Serializer): class CourseSerializer(serializers.Serializer):
""" Serializer for Courses """ """ Serializer for Courses """
id = serializers.CharField(source='id') id = serializers.CharField(source='id')
name = serializers.CharField(source='display_name') name = serializers.CharField(source='name')
category = serializers.CharField(source='location.category') category = serializers.CharField(source='category')
number = serializers.CharField(source='location.course') number = serializers.CharField(source='number')
org = serializers.CharField(source='location.org') org = serializers.CharField(source='org')
uri = serializers.SerializerMethodField('get_uri') uri = serializers.CharField(source='uri')
course_image_url = serializers.CharField(source='course_image_url')
resources = serializers.CharField(source='resources')
due = serializers.DateTimeField() due = serializers.DateTimeField()
start = serializers.DateTimeField() start = serializers.DateTimeField()
end = serializers.DateTimeField() end = serializers.DateTimeField()
......
...@@ -300,6 +300,28 @@ class CoursesApiTests(TestCase): ...@@ -300,6 +300,28 @@ class CoursesApiTests(TestCase):
matched_course = True matched_course = True
self.assertTrue(matched_course) self.assertTrue(matched_course)
def test_courses_list_get_with_filter(self):
test_uri = self.base_courses_uri
courses = [self.test_course_id, unicode(self.empty_course.id)]
params = {'course_id': ','.join(courses).encode('utf-8')}
response = self.do_get('{}/?{}'.format(test_uri, urlencode(params)))
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data['results']), 2)
self.assertIsNotNone(response.data['count'])
self.assertIsNotNone(response.data['num_pages'])
courses_in_result = []
for course in response.data['results']:
courses_in_result.append(course['id'])
if course['id'] == self.test_course_id:
self.assertEqual(course['name'], self.test_course_name)
self.assertEqual(course['number'], self.test_course_number)
self.assertEqual(course['org'], self.test_course_org)
confirm_uri = self.test_server_prefix + test_uri + '/' + course['id']
self.assertEqual(course['uri'], confirm_uri)
self.assertIsNotNone(course['course_image_url'])
self.assertItemsEqual(courses, courses_in_result)
def test_course_detail_without_date_values(self): def test_course_detail_without_date_values(self):
create_course_with_out_date_values = CourseFactory.create() # pylint: disable=C0103 create_course_with_out_date_values = CourseFactory.create() # pylint: disable=C0103
test_uri = self.base_courses_uri + '/' + unicode(create_course_with_out_date_values.id) test_uri = self.base_courses_uri + '/' + unicode(create_course_with_out_date_values.id)
...@@ -323,8 +345,8 @@ class CoursesApiTests(TestCase): ...@@ -323,8 +345,8 @@ class CoursesApiTests(TestCase):
self.assertEqual(response.data['uri'], confirm_uri) self.assertEqual(response.data['uri'], confirm_uri)
def test_courses_detail_get_with_child_content(self): def test_courses_detail_get_with_child_content(self):
test_uri = self.base_courses_uri + '/' + self.test_course_id + '?depth=100' test_uri = self.base_courses_uri + '/' + self.test_course_id
response = self.do_get(test_uri) response = self.do_get('{}?depth=100'.format(test_uri))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertGreater(len(response.data), 0) self.assertGreater(len(response.data), 0)
self.assertEqual(response.data['id'], self.test_course_id) self.assertEqual(response.data['id'], self.test_course_id)
......
...@@ -30,7 +30,7 @@ from student.roles import CourseRole, CourseAccessRole, CourseInstructorRole, Co ...@@ -30,7 +30,7 @@ from student.roles import CourseRole, CourseAccessRole, CourseInstructorRole, Co
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from api_manager.courseware_access import get_course, get_course_child, get_course_leaf_nodes, get_course_key, \ from api_manager.courseware_access import get_course, get_course_child, get_course_leaf_nodes, get_course_key, \
course_exists, get_modulestore course_exists, get_modulestore, get_course_descriptor
from api_manager.models import CourseGroupRelationship, CourseContentGroupRelationship, GroupProfile, \ from api_manager.models import CourseGroupRelationship, CourseContentGroupRelationship, GroupProfile, \
CourseModuleCompletion CourseModuleCompletion
from api_manager.permissions import SecureAPIView, SecureListAPIView from api_manager.permissions import SecureAPIView, SecureListAPIView
...@@ -336,6 +336,44 @@ def _get_aggregate_exclusion_user_ids(course_key): ...@@ -336,6 +336,44 @@ def _get_aggregate_exclusion_user_ids(course_key):
return exclude_user_ids return exclude_user_ids
def _get_course_data(request, course_key, course_descriptor, depth=0):
"""
creates a dict of course attributes
"""
if depth > 0:
data = _serialize_content_with_children(
request,
course_key,
course_descriptor, # Primer for recursive function
depth
)
data['content'] = data['children']
data.pop('children')
else:
data = _serialize_content(
request,
course_key,
course_descriptor
)
base_uri_without_qs = generate_base_uri(request, True)
data['course_image_url'] = request.build_absolute_uri(course_image_url(course_descriptor))
data['resources'] = []
resource_uri = '{}/content/'.format(base_uri_without_qs)
data['resources'].append({'uri': resource_uri})
resource_uri = '{}/groups/'.format(base_uri_without_qs)
data['resources'].append({'uri': resource_uri})
resource_uri = '{}/overview/'.format(base_uri_without_qs)
data['resources'].append({'uri': resource_uri})
resource_uri = '{}/updates/'.format(base_uri_without_qs)
data['resources'].append({'uri': resource_uri})
resource_uri = '{}/static_tabs/'.format(base_uri_without_qs)
data['resources'].append({'uri': resource_uri})
resource_uri = '{}/users/'.format(base_uri_without_qs)
data['resources'].append({'uri': resource_uri})
return data
class CourseContentList(SecureAPIView): class CourseContentList(SecureAPIView):
""" """
**Use Case** **Use Case**
...@@ -503,11 +541,13 @@ class CoursesList(SecureListAPIView): ...@@ -503,11 +541,13 @@ class CoursesList(SecureListAPIView):
**Use Case** **Use Case**
CoursesList returns paginated list of courses in the edX Platform. You can CoursesList returns paginated list of courses in the edX Platform. You can
use the uri value in the response to get details of the course. use the uri value in the response to get details of the course. course list can be
filtered by course_id
**Example Request** **Example Request**
GET /api/courses GET /api/courses
GET /api/courses/?course_id={course_id1},{course_id2}
**Response Values** **Response Values**
...@@ -528,8 +568,21 @@ class CoursesList(SecureListAPIView): ...@@ -528,8 +568,21 @@ class CoursesList(SecureListAPIView):
serializer_class = CourseSerializer serializer_class = CourseSerializer
def get_queryset(self): def get_queryset(self):
course_descriptors = get_modulestore().get_courses() course_ids = self.request.QUERY_PARAMS.get('course_id', None)
return course_descriptors depth = self.request.QUERY_PARAMS.get('depth', 0)
course_descriptors = []
if course_ids:
course_ids = course_ids.split(',')
for course_id in course_ids:
course_key = get_course_key(course_id)
course_descriptor = get_course_descriptor(course_key, 0)
course_descriptors.append(course_descriptor)
else:
course_descriptors = get_modulestore().get_courses()
results = [_get_course_data(self.request, descriptor.id, descriptor, depth)
for descriptor in course_descriptors]
return results
class CoursesDetail(SecureAPIView): class CoursesDetail(SecureAPIView):
...@@ -590,38 +643,7 @@ class CoursesDetail(SecureAPIView): ...@@ -590,38 +643,7 @@ class CoursesDetail(SecureAPIView):
course_descriptor, course_key, course_content = get_course(request, request.user, course_id, depth=depth_int) # pylint: disable=W0612 course_descriptor, course_key, course_content = get_course(request, request.user, course_id, depth=depth_int) # pylint: disable=W0612
if not course_descriptor: if not course_descriptor:
return Response({}, status=status.HTTP_404_NOT_FOUND) return Response({}, status=status.HTTP_404_NOT_FOUND)
if depth_int > 0: response_data = _get_course_data(request, course_key, course_descriptor, depth_int)
response_data = _serialize_content_with_children(
request,
course_key,
course_descriptor, # Primer for recursive function
depth_int
)
response_data['content'] = response_data['children']
response_data.pop('children')
else:
response_data = _serialize_content(
request,
course_key,
course_descriptor
)
base_uri = generate_base_uri(request)
response_data['uri'] = base_uri
base_uri_without_qs = generate_base_uri(request, True)
response_data['course_image_url'] = request.build_absolute_uri(course_image_url(course_descriptor))
response_data['resources'] = []
resource_uri = '{}/content/'.format(base_uri_without_qs)
response_data['resources'].append({'uri': resource_uri})
resource_uri = '{}/groups/'.format(base_uri_without_qs)
response_data['resources'].append({'uri': resource_uri})
resource_uri = '{}/overview/'.format(base_uri_without_qs)
response_data['resources'].append({'uri': resource_uri})
resource_uri = '{}/updates/'.format(base_uri_without_qs)
response_data['resources'].append({'uri': resource_uri})
resource_uri = '{}/static_tabs/'.format(base_uri_without_qs)
response_data['resources'].append({'uri': resource_uri})
resource_uri = '{}/users/'.format(base_uri_without_qs)
response_data['resources'].append({'uri': resource_uri})
return Response(response_data, status=status.HTTP_200_OK) return Response(response_data, status=status.HTTP_200_OK)
......
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