Skip to content

Commit

Permalink
Merge pull request #700 from edx-solutions/msaqib52/YONK-318
Browse files Browse the repository at this point in the history
YONK-318: Update organizations list API to return number of courses
  • Loading branch information
msaqib52 committed May 12, 2016
2 parents 342a66b + a7ca9a6 commit 9838f44
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 6 deletions.
17 changes: 16 additions & 1 deletion lms/djangoapps/api_manager/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from django.conf import settings

from api_manager.utils import get_client_ip_address, address_exists_in_network
from rest_framework import permissions, generics, filters, pagination, serializers
from rest_framework import permissions, generics, filters, pagination, serializers, viewsets
from rest_framework.views import APIView

from api_manager.utils import str2bool
Expand Down Expand Up @@ -169,3 +169,18 @@ def get_paginate_by(self):
return None
else:
return super(SecureListAPIView, self).get_paginate_by()


class APIModelViewSet(PaginationMixin, viewsets.ModelViewSet):
"""
ModelViewSet used for pagination
"""
def get_paginate_by(self): # pylint: disable=W0221
"""
Override to return size of pages, if page_size parameter in request is zero don't paginate
"""
page_size = self.request.QUERY_PARAMS.get('page_size')
if page_size and int(page_size) == 0:
return None
else:
return super(APIModelViewSet, self).get_paginate_by()
11 changes: 11 additions & 0 deletions lms/djangoapps/organizations/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,14 @@ class Meta:
fields = ('url', 'id', 'name', 'display_name', 'contact_name', 'contact_email', 'contact_phone',
'logo_url', 'created', 'modified')
read_only = ('url', 'id', 'created',)


class OrganizationWithCourseCountSerializer(BasicOrganizationSerializer):
""" Serializer for Organization fields with number of courses """
number_of_courses = serializers.IntegerField(source='number_of_courses')

class Meta(object):
""" Serializer/field specification """
model = Organization
fields = ('url', 'id', 'name', 'display_name', 'number_of_courses', 'contact_name', 'contact_email',
'contact_phone', 'logo_url', 'created', 'modified')
50 changes: 50 additions & 0 deletions lms/djangoapps/organizations/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,56 @@ def test_organizations_list_post(self):
response = self.do_get(users_get_uri)
self.assertEqual(len(response.data), len(users))

def test_organizations_list_get(self):
courses = CourseFactory.create_batch(5)
group = GroupFactory.create()

organizations = []
for i in xrange(30):
data = {
'name': 'Test Organization {}'.format(i),
'display_name': 'Test Name {}'.format(i),
'contact_name': 'Test Contact {}'.format(i),
'contact_email': 'test{}@test.com'.format(i),
'contact_phone': '12313{}'.format(i),
}
organizations.append(self.setup_test_organization(org_data=data))

group.organizations.add(organizations[0]['id'])

for course in courses:
CourseGroupRelationship.objects.create(course_id=course.id, group=group)

test_uri = '{}'.format(self.base_organizations_uri)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['count'], len(organizations))
self.assertEqual(len(response.data['results']), 20)
self.assertEqual(response.data['num_pages'], 2)
for i, organization in enumerate(response.data['results']):
uri = '{}{}{}/'.format(self.test_server_prefix, self.base_organizations_uri, organizations[i]['id'])
self.assertEqual(organization['url'], uri)
self.assertEqual(organization['id'], organizations[i]['id'])
self.assertEqual(organization['name'], organizations[i]['name'])
self.assertEqual(organization['display_name'], organizations[i]['display_name'])
self.assertEqual(organization['contact_name'], organizations[i]['contact_name'])
self.assertEqual(organization['contact_email'], organizations[i]['contact_email'])
self.assertEqual(organization['contact_phone'], organizations[i]['contact_phone'])
self.assertEqual(organization['logo_url'], self.test_organization_logo_url)
number_of_courses = 0 if i else 5
self.assertEqual(organization['number_of_courses'], number_of_courses)
self.assertIsNotNone(organization['created'])
self.assertIsNotNone(organization['modified'])

# fetch organization data with page outside range
response = self.do_get('{}?page=5'.format(test_uri))
self.assertEqual(response.status_code, 404)

# test with page_size 0, should not paginate and return all results
response = self.do_get('{}?page_size=0'.format(test_uri))
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data), len(organizations))

def test_organizations_detail_get(self):
org = self.setup_test_organization()
test_uri = '{}{}/'.format(self.base_organizations_uri, org['id'])
Expand Down
15 changes: 10 additions & 5 deletions lms/djangoapps/organizations/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from django.db import IntegrityError
from django.utils.translation import ugettext as _

from rest_framework import status, viewsets
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.exceptions import ParseError
Expand All @@ -18,24 +18,29 @@
from organizations.models import Organization, OrganizationGroupUser
from api_manager.users.serializers import SimpleUserSerializer
from api_manager.groups.serializers import GroupSerializer
from api_manager.permissions import SecureListAPIView
from api_manager.permissions import SecureListAPIView, APIModelViewSet
from api_manager.utils import str2bool
from gradebook.models import StudentGradebook
from student.models import CourseEnrollment
from student.roles import get_aggregate_exclusion_user_ids

from .serializers import OrganizationSerializer, BasicOrganizationSerializer
from .serializers import OrganizationSerializer, BasicOrganizationSerializer, OrganizationWithCourseCountSerializer


class OrganizationsViewSet(viewsets.ModelViewSet):
class OrganizationsViewSet(APIModelViewSet):
"""
Django Rest Framework ViewSet for the Organization model.
"""
serializer_class = OrganizationSerializer
model = Organization

def list(self, request, *args, **kwargs):
self.serializer_class = BasicOrganizationSerializer
self.serializer_class = OrganizationWithCourseCountSerializer
queryset = self.get_queryset()
self.queryset = queryset.annotate(
number_of_courses=Count('groups__coursegrouprelationship__course_id', distinct=True)
)

return super(OrganizationsViewSet, self).list(request, *args, **kwargs)

def retrieve(self, request, *args, **kwargs):
Expand Down

0 comments on commit 9838f44

Please sign in to comment.