Files
edx-platform/lms/djangoapps/program_enrollments/rest_api/v1/serializers.py
2021-02-22 12:58:16 +05:00

228 lines
7.3 KiB
Python

"""
API Serializers
"""
from rest_framework import serializers
from lms.djangoapps.program_enrollments.api import is_course_staff_enrollment
from lms.djangoapps.program_enrollments.models import ProgramCourseEnrollment, ProgramEnrollment
from .constants import CourseRunProgressStatuses
# pylint: disable=abstract-method
class InvalidStatusMixin:
"""
Mixin to provide has_invalid_status method
"""
def has_invalid_status(self):
"""
Returns whether or not this serializer has an invalid error choice on
the "status" field.
"""
for status_error in self.errors.get('status', []):
if status_error.code == 'invalid_choice':
return True
return False
class ProgramEnrollmentSerializer(serializers.Serializer):
"""
Serializer for displaying enrollments in a program.
"""
student_key = serializers.CharField(source='external_user_key')
status = serializers.CharField()
account_exists = serializers.SerializerMethodField()
curriculum_uuid = serializers.UUIDField()
username = serializers.SerializerMethodField()
email = serializers.SerializerMethodField()
class Meta:
model = ProgramEnrollment
def get_account_exists(self, obj):
return bool(obj.user)
def get_username(self, obj):
if obj.user:
return obj.user.username
return ""
def get_email(self, obj):
if obj.user:
return obj.user.email
return ""
class ProgramEnrollmentRequestMixin(InvalidStatusMixin, serializers.Serializer):
"""
Base fields for all program enrollment related serializers.
"""
student_key = serializers.CharField(allow_blank=False, source='external_user_key')
# We could have made this a ChoiceField on ProgramEnrollmentStatuses.__ALL__;
# however, we instead check statuses in api/writing.py,
# returning INVALID_STATUS for individual bad statuses instead of raising
# a ValidationError for the entire request.
status = serializers.CharField(allow_blank=False)
class ProgramEnrollmentCreateRequestSerializer(ProgramEnrollmentRequestMixin):
"""
Serializer for program enrollment creation requests.
"""
curriculum_uuid = serializers.UUIDField()
class ProgramEnrollmentUpdateRequestSerializer(ProgramEnrollmentRequestMixin):
"""
Serializer for program enrollment update requests.
"""
class ProgramCourseEnrollmentSerializer(serializers.Serializer):
"""
Serializer for displaying program-course enrollments.
"""
student_key = serializers.SerializerMethodField()
status = serializers.CharField()
account_exists = serializers.SerializerMethodField()
curriculum_uuid = serializers.SerializerMethodField()
course_staff = serializers.SerializerMethodField()
class Meta:
model = ProgramCourseEnrollment
def get_student_key(self, obj):
return obj.program_enrollment.external_user_key
def get_account_exists(self, obj):
return bool(obj.program_enrollment.user)
def get_curriculum_uuid(self, obj):
return str(obj.program_enrollment.curriculum_uuid)
def get_course_staff(self, obj):
return is_course_staff_enrollment(obj)
class ProgramCourseEnrollmentRequestSerializer(serializers.Serializer, InvalidStatusMixin):
"""
Serializer for request to create a ProgramCourseEnrollment
"""
student_key = serializers.CharField(allow_blank=False, source='external_user_key')
# We could have made this a ChoiceField on ProgramCourseEnrollmentStatuses.__ALL__;
# however, we instead check statuses in api/writing.py,
# returning INVALID_STATUS for individual bad statuses instead of raising
# a ValidationError for the entire request.
status = serializers.CharField(allow_blank=False)
course_staff = serializers.BooleanField(required=False, default=None)
class ProgramCourseGradeSerializer(serializers.Serializer):
"""
Serializer for a user's grade in a program courserun.
Meant to be used with BaseProgramCourseGrade.
"""
# Required
student_key = serializers.SerializerMethodField()
# From ProgramCourseGradeOk only
passed = serializers.BooleanField(required=False)
percent = serializers.FloatField(required=False)
letter_grade = serializers.CharField(required=False)
# From ProgramCourseGradeError only
error = serializers.CharField(required=False)
def get_student_key(self, obj):
return obj.program_course_enrollment.program_enrollment.external_user_key
class DueDateSerializer(serializers.Serializer):
"""
Serializer for a due date.
"""
name = serializers.CharField()
url = serializers.CharField()
date = serializers.DateTimeField()
class CourseRunOverviewSerializer(serializers.Serializer):
"""
Serializer for a course run overview.
"""
STATUS_CHOICES = [
CourseRunProgressStatuses.IN_PROGRESS,
CourseRunProgressStatuses.UPCOMING,
CourseRunProgressStatuses.COMPLETED
]
course_run_id = serializers.CharField(
help_text="ID for the course run.",
)
display_name = serializers.CharField(
help_text="Display name of the course run.",
)
resume_course_run_url = serializers.CharField(
required=False,
help_text=(
"The absolute url that takes the user back to their position in the "
"course run; if absent, user has not made progress in the course."
),
)
course_run_url = serializers.CharField(
help_text="The absolute url for the course run.",
)
start_date = serializers.DateTimeField(
help_text="Start date for the course run; null if no start date.",
)
end_date = serializers.DateTimeField(
help_text="End date for the course run; null if no end date.",
)
course_run_status = serializers.ChoiceField(
allow_blank=False,
choices=STATUS_CHOICES,
help_text="The user's status of the course run.",
)
emails_enabled = serializers.BooleanField(
required=False,
help_text=(
"Boolean representing whether emails are enabled for the course;"
"if absent, the bulk email feature is either not enable at the platform"
"level or is not enabled for the course; if True or False, bulk email"
"feature is enabled, and value represents whether or not user wants"
"to receive emails."
),
)
due_dates = serializers.ListField(
child=DueDateSerializer(),
help_text=(
"List of subsection due dates for the course run. "
"Due dates are only returned if the course run is in progress."
),
)
micromasters_title = serializers.CharField(
required=False,
help_text=(
"Title of the MicroMasters program that the course run is a part of; "
"if absent, the course run is not a part of a MicroMasters program."
),
)
certificate_download_url = serializers.CharField(
required=False,
help_text=(
"URL to download a certificate, if available; "
"if absent, certificate is not downloadable."
),
)
class CourseRunOverviewListSerializer(serializers.Serializer):
"""
Serializer for a list of course run overviews.
"""
course_runs = serializers.ListField(child=CourseRunOverviewSerializer())