207 lines
7.5 KiB
Python
207 lines
7.5 KiB
Python
"""
|
|
Course API Views
|
|
"""
|
|
|
|
from django.core.exceptions import ValidationError
|
|
from rest_framework.generics import ListAPIView, RetrieveAPIView
|
|
|
|
from openedx.core.lib.api.paginators import NamespacedPageNumberPagination
|
|
from openedx.core.lib.api.view_utils import view_auth_classes, DeveloperErrorViewMixin
|
|
from .api import course_detail, list_courses
|
|
from .forms import CourseDetailGetForm, CourseListGetForm
|
|
from .serializers import CourseSerializer, CourseDetailSerializer
|
|
|
|
|
|
@view_auth_classes(is_authenticated=False)
|
|
class CourseDetailView(DeveloperErrorViewMixin, RetrieveAPIView):
|
|
"""
|
|
**Use Cases**
|
|
|
|
Request information on a course
|
|
|
|
**Example Requests**
|
|
|
|
GET /api/courses/v1/courses/{course_key}/
|
|
|
|
**Response Values**
|
|
|
|
Body consists of the following fields:
|
|
|
|
* blocks_url: Used to fetch the course blocks
|
|
* effort: A textual description of the weekly hours of effort expected
|
|
in the course.
|
|
* end: Date the course ends
|
|
* enrollment_end: Date enrollment ends
|
|
* enrollment_start: Date enrollment begins
|
|
* id: A unique identifier of the course; a serialized representation
|
|
of the opaque key identifying the course.
|
|
* media: An object that contains named media items. Included here:
|
|
* course_image: An image to show for the course. Represented
|
|
as an object with the following fields:
|
|
* uri: The location of the image
|
|
* name: Name of the course
|
|
* number: Catalog number of the course
|
|
* org: Name of the organization that owns the course
|
|
* overview: A possibly verbose HTML textual description of the course.
|
|
Note: this field is only included in the Course Detail view, not
|
|
the Course List view.
|
|
* short_description: A textual description of the course
|
|
* start: Date the course begins
|
|
* start_display: Readably formatted start of the course
|
|
* start_type: Hint describing how `start_display` is set. One of:
|
|
* `"string"`: manually set
|
|
* `"timestamp"`: generated form `start` timestamp
|
|
* `"empty"`: the start date should not be shown
|
|
|
|
Deprecated fields:
|
|
|
|
* course_id: Course key (use 'id' instead)
|
|
|
|
**Parameters:**
|
|
|
|
username (optional):
|
|
The username of the specified user for whom the course data
|
|
is being accessed. The username is not only required if the API is
|
|
requested by an Anonymous user.
|
|
|
|
**Returns**
|
|
|
|
* 200 on success with above fields.
|
|
* 400 if an invalid parameter was sent or the username was not provided
|
|
for an authenticated request.
|
|
* 403 if a user who does not have permission to masquerade as
|
|
another user specifies a username other than their own.
|
|
* 404 if the course is not available or cannot be seen.
|
|
|
|
Example response:
|
|
|
|
{
|
|
"blocks_url": "/api/courses/v1/blocks/?course_id=edX%2Fexample%2F2012_Fall",
|
|
"media": {
|
|
"course_image": {
|
|
"uri": "/c4x/edX/example/asset/just_a_test.jpg",
|
|
"name": "Course Image"
|
|
}
|
|
},
|
|
"description": "An example course.",
|
|
"end": "2015-09-19T18:00:00Z",
|
|
"enrollment_end": "2015-07-15T00:00:00Z",
|
|
"enrollment_start": "2015-06-15T00:00:00Z",
|
|
"course_id": "edX/example/2012_Fall",
|
|
"name": "Example Course",
|
|
"number": "example",
|
|
"org": "edX",
|
|
"overview: "<p>A verbose description of the course.</p>"
|
|
"start": "2015-07-17T12:00:00Z",
|
|
"start_display": "July 17, 2015",
|
|
"start_type": "timestamp"
|
|
}
|
|
"""
|
|
|
|
serializer_class = CourseDetailSerializer
|
|
|
|
def get_object(self):
|
|
"""
|
|
Return the requested course object, if the user has appropriate
|
|
permissions.
|
|
"""
|
|
requested_params = self.request.query_params.copy()
|
|
requested_params.update({'course_key': self.kwargs['course_key_string']})
|
|
form = CourseDetailGetForm(requested_params, initial={'requesting_user': self.request.user})
|
|
if not form.is_valid():
|
|
raise ValidationError(form.errors)
|
|
|
|
return course_detail(
|
|
self.request,
|
|
form.cleaned_data['username'],
|
|
form.cleaned_data['course_key'],
|
|
)
|
|
|
|
|
|
@view_auth_classes(is_authenticated=False)
|
|
class CourseListView(DeveloperErrorViewMixin, ListAPIView):
|
|
"""
|
|
**Use Cases**
|
|
|
|
Request information on all courses visible to the specified user.
|
|
|
|
**Example Requests**
|
|
|
|
GET /api/courses/v1/courses/
|
|
|
|
**Response Values**
|
|
|
|
Body comprises a list of objects as returned by `CourseDetailView`.
|
|
|
|
**Parameters**
|
|
|
|
username (optional):
|
|
The username of the specified user whose visible courses we
|
|
want to see. The username is not required only if the API is
|
|
requested by an Anonymous user.
|
|
|
|
org (optional):
|
|
If specified, visible `CourseOverview` objects are filtered
|
|
such that only those belonging to the organization with the
|
|
provided org code (e.g., "HarvardX") are returned.
|
|
Case-insensitive.
|
|
|
|
mobile (optional):
|
|
If specified, only visible `CourseOverview` objects that are
|
|
designated as mobile_available are returned.
|
|
|
|
**Returns**
|
|
|
|
* 200 on success, with a list of course discovery objects as returned
|
|
by `CourseDetailView`.
|
|
* 400 if an invalid parameter was sent or the username was not provided
|
|
for an authenticated request.
|
|
* 403 if a user who does not have permission to masquerade as
|
|
another user specifies a username other than their own.
|
|
* 404 if the specified user does not exist, or the requesting user does
|
|
not have permission to view their courses.
|
|
|
|
Example response:
|
|
|
|
[
|
|
{
|
|
"blocks_url": "/api/courses/v1/blocks/?course_id=edX%2Fexample%2F2012_Fall",
|
|
"media": {
|
|
"course_image": {
|
|
"uri": "/c4x/edX/example/asset/just_a_test.jpg",
|
|
"name": "Course Image"
|
|
}
|
|
},
|
|
"description": "An example course.",
|
|
"end": "2015-09-19T18:00:00Z",
|
|
"enrollment_end": "2015-07-15T00:00:00Z",
|
|
"enrollment_start": "2015-06-15T00:00:00Z",
|
|
"course_id": "edX/example/2012_Fall",
|
|
"name": "Example Course",
|
|
"number": "example",
|
|
"org": "edX",
|
|
"start": "2015-07-17T12:00:00Z",
|
|
"start_display": "July 17, 2015",
|
|
"start_type": "timestamp"
|
|
}
|
|
]
|
|
"""
|
|
|
|
pagination_class = NamespacedPageNumberPagination
|
|
serializer_class = CourseSerializer
|
|
|
|
def get_queryset(self):
|
|
"""
|
|
Return a list of courses visible to the user.
|
|
"""
|
|
form = CourseListGetForm(self.request.query_params, initial={'requesting_user': self.request.user})
|
|
if not form.is_valid():
|
|
raise ValidationError(form.errors)
|
|
|
|
return list_courses(
|
|
self.request,
|
|
form.cleaned_data['username'],
|
|
org=form.cleaned_data['org'],
|
|
filter_=form.cleaned_data['filter_'],
|
|
)
|