70 lines
2.6 KiB
Python
70 lines
2.6 KiB
Python
"""
|
|
Serializers for Bulk Enrollment.
|
|
"""
|
|
|
|
|
|
from opaque_keys import InvalidKeyError
|
|
from opaque_keys.edx.keys import CourseKey
|
|
from rest_framework import serializers
|
|
|
|
from openedx.core.djangoapps.course_groups.cohorts import is_cohort_exists
|
|
|
|
|
|
class StringListField(serializers.ListField): # lint-amnesty, pylint: disable=missing-class-docstring
|
|
def to_internal_value(self, data):
|
|
if not data:
|
|
return []
|
|
if isinstance(data, list):
|
|
data = data[0]
|
|
return data.split(',')
|
|
|
|
|
|
class BulkEnrollmentSerializer(serializers.Serializer): # lint-amnesty, pylint: disable=abstract-method
|
|
"""Serializes enrollment information for a collection of students/emails.
|
|
|
|
This is mainly useful for implementing validation when performing bulk enrollment operations.
|
|
"""
|
|
identifiers = serializers.CharField(required=True)
|
|
courses = StringListField(required=True)
|
|
cohorts = StringListField(required=False)
|
|
action = serializers.ChoiceField(
|
|
choices=(
|
|
('enroll', 'enroll'),
|
|
('unenroll', 'unenroll')
|
|
),
|
|
required=True
|
|
)
|
|
auto_enroll = serializers.BooleanField(default=False)
|
|
email_students = serializers.BooleanField(default=False)
|
|
|
|
def validate_courses(self, value):
|
|
"""
|
|
Check that each course key in list is valid.
|
|
"""
|
|
course_keys = value
|
|
for course in course_keys:
|
|
try:
|
|
CourseKey.from_string(course)
|
|
except InvalidKeyError:
|
|
raise serializers.ValidationError(f"Course key not valid: {course}") # lint-amnesty, pylint: disable=raise-missing-from
|
|
return value
|
|
|
|
def validate(self, attrs):
|
|
"""
|
|
Check that the cohorts list is the same size as the courses list.
|
|
"""
|
|
if attrs.get('cohorts'):
|
|
if attrs['action'] != 'enroll':
|
|
raise serializers.ValidationError("Cohorts can only be used for enrollments.")
|
|
if len(attrs['cohorts']) != len(attrs['courses']):
|
|
raise serializers.ValidationError(
|
|
"If provided, the cohorts and courses should have equal number of items.")
|
|
|
|
for course_id, cohort_name in zip(attrs['courses'], attrs['cohorts']):
|
|
if not is_cohort_exists(course_key=CourseKey.from_string(course_id), name=cohort_name):
|
|
raise serializers.ValidationError("cohort {cohort_name} not found in course {course_id}.".format(
|
|
cohort_name=cohort_name, course_id=course_id)
|
|
)
|
|
|
|
return attrs
|