feat: add a POST endpoint for listing courses (#35586)

* feat: add a POST endpoint for listing courses
This commit is contained in:
Paulo Viadanna
2025-08-21 14:56:18 -03:00
committed by GitHub
parent 0fbfc1cf54
commit d132efa08d
3 changed files with 35 additions and 1 deletions

View File

@@ -2623,6 +2623,7 @@ paths:
**Example Requests**
GET /api/courses/v1/courses/
POST /api/courses/v1/courses/
**Response Values**
@@ -2698,6 +2699,10 @@ paths:
"start_type": "timestamp"
}
]
**Note**
The POST /api/courses/v1/courses/ reads `request.body` for parameters, allowing for
larger input than the query string.
parameters:
- name: page
in: query

View File

@@ -250,6 +250,18 @@ class CourseListViewTestCaseMultipleCourses(CourseApiTestViewMixin, ModuleStoreT
ids = {c['course_id'] for c in response.json()['results']}
self.assertEqual(ids, {str(self.course.id)})
def test_filter_post(self):
"""Verify that CourseOverviews are filtered by the provided org key in a POST request."""
self.setup_user(self.staff_user)
# Create a second course to be filtered out of queries.
alternate_course = self.create_course(
org=md5(self.course.org.encode('utf-8')).hexdigest()
)
response = self.client.post(self.url, data={'course_keys': str(self.course.id)})
assert all((course['org'] == self.course.org) for course in response.json()['results'])
class CourseDetailViewTestCase(CourseApiTestViewMixin, SharedModuleStoreTestCase):
"""

View File

@@ -254,6 +254,7 @@ class CourseListView(DeveloperErrorViewMixin, ListAPIView):
**Example Requests**
GET /api/courses/v1/courses/
POST /api/courses/v1/courses/
**Response Values**
@@ -329,6 +330,10 @@ class CourseListView(DeveloperErrorViewMixin, ListAPIView):
"start_type": "timestamp"
}
]
**Note**
The POST /api/courses/v1/courses/ reads `request.body` for parameters, allowing for
larger input than the query string.
"""
class CourseListPageNumberPagination(LazyPageNumberPagination):
max_page_size = 100
@@ -341,7 +346,13 @@ class CourseListView(DeveloperErrorViewMixin, ListAPIView):
"""
Yield courses visible to the user.
"""
form = CourseListGetForm(self.request.query_params, initial={'requesting_user': self.request.user})
form_data = self.request.query_params
if self.request.method == 'POST':
form_data = self.request.data
form = CourseListGetForm(
data=form_data,
initial={'requesting_user': self.request.user}
)
if not form.is_valid():
raise ValidationError(form.errors)
return list_courses(
@@ -356,6 +367,12 @@ class CourseListView(DeveloperErrorViewMixin, ListAPIView):
mobile_search=form.cleaned_data.get('mobile_search', False),
)
def post(self, request, *args, **kwargs):
"""
POST courses filter.
"""
return self.list(request, *args, **kwargs)
class CourseIdListUserThrottle(UserRateThrottle):
"""Limit the number of requests users can make to the course list id API."""