feat: added support of multiple course ids in enrollment API and fixed failing case (#36700)
* feat: added support of multiple course ids in enrollment API and fixed failing case * refactor: handled course IDs along with course run IDs * refactor: added dosctring and renamed variable * fix: added temp mixin * test: added unit tests of added case
This commit is contained in:
committed by
GitHub
parent
db49b2d0a3
commit
2d66047f7c
@@ -18,6 +18,7 @@ class CourseEnrollmentsApiListForm(Form):
|
||||
MAX_INPUT_COUNT = 100
|
||||
username = CharField(required=False)
|
||||
course_id = CharField(required=False)
|
||||
course_ids = CharField(required=False)
|
||||
email = CharField(required=False)
|
||||
|
||||
def clean_course_id(self):
|
||||
@@ -51,6 +52,24 @@ class CourseEnrollmentsApiListForm(Form):
|
||||
return usernames
|
||||
return usernames_csv_string
|
||||
|
||||
def clean_course_ids(self):
|
||||
"""
|
||||
Validate a string of comma-separated course IDs and return a list of course IDs.
|
||||
"""
|
||||
course_ids_csv_string = self.cleaned_data.get('course_ids')
|
||||
if course_ids_csv_string:
|
||||
course_ids = course_ids_csv_string.split(',')
|
||||
if len(course_ids) > self.MAX_INPUT_COUNT:
|
||||
raise ValidationError(
|
||||
"Too many course_ids in a single request - {}. A maximum of {} is allowed".format(
|
||||
len(course_ids),
|
||||
self.MAX_INPUT_COUNT,
|
||||
)
|
||||
)
|
||||
return course_ids
|
||||
|
||||
return course_ids_csv_string
|
||||
|
||||
def clean_email(self):
|
||||
"""
|
||||
Validate a string of comma-separated emails and return a list of emails.
|
||||
|
||||
@@ -210,5 +210,69 @@
|
||||
"created": "2018-01-01T00:00:01Z"
|
||||
}
|
||||
]
|
||||
],
|
||||
[
|
||||
{
|
||||
"course_ids": "course-v1:e+d+X,x+y+Z"
|
||||
},
|
||||
[
|
||||
{
|
||||
"course_id": "course-v1:e+d+X",
|
||||
"is_active": true,
|
||||
"mode": "honor",
|
||||
"user": "student1",
|
||||
"created": "2018-01-01T00:00:01Z"
|
||||
},
|
||||
{
|
||||
"course_id": "course-v1:e+d+X",
|
||||
"is_active": true,
|
||||
"mode": "honor",
|
||||
"user": "student2",
|
||||
"created": "2018-01-01T00:00:01Z"
|
||||
},
|
||||
{
|
||||
"course_id": "course-v1:x+y+Z",
|
||||
"is_active": true,
|
||||
"mode": "verified",
|
||||
"user": "staff",
|
||||
"created": "2018-01-01T00:00:01Z"
|
||||
},
|
||||
{
|
||||
"course_id": "course-v1:x+y+Z",
|
||||
"is_active": true,
|
||||
"mode": "honor",
|
||||
"user": "student2",
|
||||
"created": "2018-01-01T00:00:01Z"
|
||||
},
|
||||
{
|
||||
"course_id": "course-v1:x+y+Z",
|
||||
"is_active": true,
|
||||
"mode": "verified",
|
||||
"user": "student3",
|
||||
"created": "2018-01-01T00:00:01Z"
|
||||
}
|
||||
]
|
||||
],
|
||||
[
|
||||
{
|
||||
"course_ids": "course-v1:e+d+X,x+y+Z",
|
||||
"username": "student2"
|
||||
},
|
||||
[
|
||||
{
|
||||
"course_id": "course-v1:e+d+X",
|
||||
"is_active": true,
|
||||
"mode": "honor",
|
||||
"user": "student2",
|
||||
"created": "2018-01-01T00:00:01Z"
|
||||
},
|
||||
{
|
||||
"course_id": "course-v1:x+y+Z",
|
||||
"is_active": true,
|
||||
"mode": "honor",
|
||||
"user": "student2",
|
||||
"created": "2018-01-01T00:00:01Z"
|
||||
}
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
@@ -11,6 +11,7 @@ from django.core.exceptions import ( # lint-amnesty, pylint: disable=wrong-impo
|
||||
ValidationError,
|
||||
)
|
||||
from django.db import IntegrityError # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from django.db.models import Q # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from django.utils.decorators import method_decorator # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from edx_rest_framework_extensions.auth.jwt.authentication import (
|
||||
JwtAuthentication,
|
||||
@@ -934,6 +935,8 @@ class CourseEnrollmentsApiListView(DeveloperErrorViewMixin, ListAPIView):
|
||||
|
||||
GET /api/enrollment/v1/enrollments?course_id={course_id}
|
||||
|
||||
GET /api/enrollment/v1/enrollments?course_ids={course_id},{course_id},{course_id}
|
||||
|
||||
GET /api/enrollment/v1/enrollments?username={username},{username},{username}
|
||||
|
||||
GET /api/enrollment/v1/enrollments?course_id={course_id}&username={username}
|
||||
@@ -945,6 +948,10 @@ class CourseEnrollmentsApiListView(DeveloperErrorViewMixin, ListAPIView):
|
||||
* course_id: Filters the result to course enrollments for the course corresponding to the
|
||||
given course ID. The value must be URL encoded. Optional.
|
||||
|
||||
* course_ids: List of comma-separated course IDs. Filters the result to course enrollments
|
||||
for the courses corresponding to the given course IDs. Course IDs could be course run IDs
|
||||
or course IDs. The value must be URL encoded. Optional.
|
||||
|
||||
* username: List of comma-separated usernames. Filters the result to the course enrollments
|
||||
of the given users. Optional.
|
||||
|
||||
@@ -1011,13 +1018,20 @@ class CourseEnrollmentsApiListView(DeveloperErrorViewMixin, ListAPIView):
|
||||
if not form.is_valid():
|
||||
raise ValidationError(form.errors)
|
||||
|
||||
queryset = CourseEnrollment.objects.all()
|
||||
queryset = CourseEnrollment.objects.all().select_related("user", "course")
|
||||
course_id = form.cleaned_data.get("course_id")
|
||||
course_ids = form.cleaned_data.get("course_ids")
|
||||
usernames = form.cleaned_data.get("username")
|
||||
emails = form.cleaned_data.get("email")
|
||||
|
||||
if course_id:
|
||||
queryset = queryset.filter(course__id=course_id)
|
||||
if course_ids:
|
||||
# Handles the case if parent course ID is sent rather than course run ID
|
||||
query = Q()
|
||||
for cid in course_ids:
|
||||
query |= Q(course__id__icontains=cid)
|
||||
queryset = queryset.filter(query)
|
||||
if usernames:
|
||||
queryset = queryset.filter(user__username__in=usernames)
|
||||
if emails:
|
||||
|
||||
Reference in New Issue
Block a user