Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Upgrading api list_course_role_members ( 2nd api ) #35105

Merged
merged 4 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 34 additions & 29 deletions lms/djangoapps/instructor/views/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
from lms.djangoapps.instructor_task.api_helper import AlreadyRunningError, QueueConnectionError
from lms.djangoapps.instructor_task.data import InstructorTaskTypes
from lms.djangoapps.instructor_task.models import ReportStore
from lms.djangoapps.instructor.views.serializer import RoleNameSerializer, UserSerializer
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort, is_course_cohorted
from openedx.core.djangoapps.course_groups.models import CourseUserGroup
Expand Down Expand Up @@ -1064,15 +1065,11 @@ def modify_access(request, course_id):
return JsonResponse(response_payload)


@require_POST
@ensure_csrf_cookie
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
@require_course_permission(permissions.EDIT_COURSE_ACCESS)
@require_post_params(rolename="'instructor', 'staff', or 'beta'")
def list_course_role_members(request, course_id):
@method_decorator(cache_control(no_cache=True, no_store=True, must_revalidate=True), name='dispatch')
class ListCourseRoleMembersView(APIView):
"""
List instructors and staff.
Requires instructor access.
View to list instructors and staff for a specific course.
Requires the user to have instructor access.

rolename is one of ['instructor', 'staff', 'beta', 'ccx_coach']

Expand All @@ -1088,33 +1085,41 @@ def list_course_role_members(request, course_id):
]
}
"""
course_id = CourseKey.from_string(course_id)
course = get_course_with_access(
request.user, 'instructor', course_id, depth=None
)
permission_classes = (IsAuthenticated, permissions.InstructorPermission)
permission_name = permissions.EDIT_COURSE_ACCESS

rolename = request.POST.get('rolename')
@method_decorator(ensure_csrf_cookie)
def post(self, request, course_id):
"""
Handles POST request to list instructors and staff.

if rolename not in ROLES:
return HttpResponseBadRequest()
Args:
request (HttpRequest): The request object containing user data.
course_id (str): The ID of the course to list instructors and staff for.

def extract_user_info(user):
""" convert user into dicts for json view """
Returns:
Response: A Response object containing the list of instructors and staff or an error message.

return {
'username': user.username,
'email': user.email,
'first_name': user.first_name,
'last_name': user.last_name,
Raises:
Http404: If the course does not exist.
"""
course_id = CourseKey.from_string(course_id)
course = get_course_with_access(
request.user, 'instructor', course_id, depth=None
)
role_serializer = RoleNameSerializer(data=request.data)
role_serializer.is_valid(raise_exception=True)
rolename = role_serializer.data['rolename']

users = list_with_level(course.id, rolename)
serializer = UserSerializer(users, many=True)

response_payload = {
'course_id': str(course_id),
rolename: serializer.data,
}

response_payload = {
'course_id': str(course_id),
rolename: list(map(extract_user_info, list_with_level(
course.id, rolename
))),
}
return JsonResponse(response_payload)
return Response(response_payload, status=status.HTTP_200_OK)


class ProblemResponseReportPostParamsSerializer(serializers.Serializer): # pylint: disable=abstract-method
Expand Down
2 changes: 1 addition & 1 deletion lms/djangoapps/instructor/views/api_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
urlpatterns = [
path('students_update_enrollment', api.students_update_enrollment, name='students_update_enrollment'),
path('register_and_enroll_students', api.register_and_enroll_students, name='register_and_enroll_students'),
path('list_course_role_members', api.list_course_role_members, name='list_course_role_members'),
path('list_course_role_members', api.ListCourseRoleMembersView.as_view(), name='list_course_role_members'),
path('modify_access', api.modify_access, name='modify_access'),
path('bulk_beta_modify_access', api.bulk_beta_modify_access, name='bulk_beta_modify_access'),
path('get_problem_responses', api.get_problem_responses, name='get_problem_responses'),
Expand Down
30 changes: 30 additions & 0 deletions lms/djangoapps/instructor/views/serializer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
""" Instructor apis serializers. """

from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _
from rest_framework import serializers

from lms.djangoapps.instructor.access import ROLES


class RoleNameSerializer(serializers.Serializer): # pylint: disable=abstract-method
"""
Serializer that describes the response of the problem response report generation API.
"""

rolename = serializers.CharField(help_text=_("Role name"))

def validate_rolename(self, value):
"""
Check that the rolename is valid.
"""
if value not in ROLES:
raise ValidationError(_("Invalid role name."))
return value


class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username', 'email', 'first_name', 'last_name']
Loading