feat!: upgrade start_certificate_regeneration to drf ( 29 ) (#35599)
* feat!: upgrading api to DRF.
This commit is contained in:
@@ -367,7 +367,7 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
|
||||
|
||||
# Assert Error Message
|
||||
assert res_json['message'] ==\
|
||||
'Please select one or more certificate statuses that require certificate regeneration.'
|
||||
'Please select certificate statuses from the list only.'
|
||||
|
||||
# Access the url passing 'certificate_statuses' that are not present in db
|
||||
url = reverse('start_certificate_regeneration', kwargs={'course_id': str(self.course.id)})
|
||||
@@ -378,7 +378,8 @@ class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
|
||||
res_json = json.loads(response.content.decode('utf-8'))
|
||||
|
||||
# Assert Error Message
|
||||
assert res_json['message'] == 'Please select certificate statuses from the list only.'
|
||||
assert (res_json['message'] ==
|
||||
'Please select certificate statuses from the list only.')
|
||||
|
||||
|
||||
@override_settings(CERT_QUEUE='certificates')
|
||||
|
||||
@@ -77,9 +77,6 @@ from common.djangoapps.util.json_request import JsonResponse, JsonResponseBadReq
|
||||
from common.djangoapps.util.views import require_global_staff # pylint: disable=unused-import
|
||||
from lms.djangoapps.bulk_email.api import is_bulk_email_feature_enabled, create_course_email
|
||||
from lms.djangoapps.certificates import api as certs_api
|
||||
from lms.djangoapps.certificates.models import (
|
||||
CertificateStatuses
|
||||
)
|
||||
from lms.djangoapps.course_home_api.toggles import course_home_mfe_progress_tab_is_active
|
||||
from lms.djangoapps.courseware.access import has_access
|
||||
from lms.djangoapps.courseware.courses import get_course_with_access
|
||||
@@ -110,6 +107,7 @@ from lms.djangoapps.instructor.views.serializer import (
|
||||
AccessSerializer,
|
||||
BlockDueDateSerializer,
|
||||
CertificateSerializer,
|
||||
CertificateStatusesSerializer,
|
||||
ListInstructorTaskInputSerializer,
|
||||
RoleNameSerializer,
|
||||
SendEmailSerializer,
|
||||
@@ -3308,46 +3306,41 @@ class StartCertificateGeneration(DeveloperErrorViewMixin, APIView):
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@transaction.non_atomic_requests
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_course_permission(permissions.START_CERTIFICATE_REGENERATION)
|
||||
@require_POST
|
||||
@common_exceptions_400
|
||||
def start_certificate_regeneration(request, course_id):
|
||||
@method_decorator(cache_control(no_cache=True, no_store=True, must_revalidate=True), name='dispatch')
|
||||
@method_decorator(transaction.non_atomic_requests, name='dispatch')
|
||||
class StartCertificateRegeneration(DeveloperErrorViewMixin, APIView):
|
||||
"""
|
||||
Start regenerating certificates for students whose certificate statuses lie with in 'certificate_statuses'
|
||||
entry in POST data.
|
||||
"""
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
certificates_statuses = request.POST.getlist('certificate_statuses', [])
|
||||
if not certificates_statuses:
|
||||
return JsonResponse(
|
||||
{'message': _('Please select one or more certificate statuses that require certificate regeneration.')},
|
||||
status=400
|
||||
)
|
||||
permission_classes = (IsAuthenticated, permissions.InstructorPermission)
|
||||
permission_name = permissions.START_CERTIFICATE_REGENERATION
|
||||
serializer_class = CertificateStatusesSerializer
|
||||
http_method_names = ['post']
|
||||
|
||||
# Check if the selected statuses are allowed
|
||||
allowed_statuses = [
|
||||
CertificateStatuses.downloadable,
|
||||
CertificateStatuses.error,
|
||||
CertificateStatuses.notpassing,
|
||||
CertificateStatuses.audit_passing,
|
||||
CertificateStatuses.audit_notpassing,
|
||||
]
|
||||
if not set(certificates_statuses).issubset(allowed_statuses):
|
||||
return JsonResponse(
|
||||
{'message': _('Please select certificate statuses from the list only.')},
|
||||
status=400
|
||||
)
|
||||
@method_decorator(transaction.non_atomic_requests, name='dispatch')
|
||||
@method_decorator(ensure_csrf_cookie)
|
||||
def post(self, request, course_id):
|
||||
"""
|
||||
certificate_statuses 'certificate_statuses' in POST data.
|
||||
"""
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
|
||||
task_api.regenerate_certificates(request, course_key, certificates_statuses)
|
||||
response_payload = {
|
||||
'message': _('Certificate regeneration task has been started. '
|
||||
'You can view the status of the generation task in the "Pending Tasks" section.'),
|
||||
'success': True
|
||||
}
|
||||
return JsonResponse(response_payload)
|
||||
if not serializer.is_valid():
|
||||
return JsonResponse(
|
||||
{'message': _('Please select certificate statuses from the list only.')},
|
||||
status=400
|
||||
)
|
||||
|
||||
certificates_statuses = serializer.validated_data['certificate_statuses']
|
||||
task_api.regenerate_certificates(request, course_key, certificates_statuses)
|
||||
response_payload = {
|
||||
'message': _('Certificate regeneration task has been started. '
|
||||
'You can view the status of the generation task in the "Pending Tasks" section.'),
|
||||
'success': True
|
||||
}
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
|
||||
@method_decorator(cache_control(no_cache=True, no_store=True, must_revalidate=True), name='dispatch')
|
||||
|
||||
@@ -83,7 +83,8 @@ urlpatterns = [
|
||||
# Certificates
|
||||
path('enable_certificate_generation', api.enable_certificate_generation, name='enable_certificate_generation'),
|
||||
path('start_certificate_generation', api.StartCertificateGeneration.as_view(), name='start_certificate_generation'),
|
||||
path('start_certificate_regeneration', api.start_certificate_regeneration, name='start_certificate_regeneration'),
|
||||
path('start_certificate_regeneration', api.StartCertificateRegeneration.as_view(),
|
||||
name='start_certificate_regeneration'),
|
||||
path('certificate_exception_view/', api.CertificateExceptionView.as_view(), name='certificate_exception_view'),
|
||||
re_path(r'^generate_certificate_exceptions/(?P<generate_for>[^/]*)', api.GenerateCertificateExceptions.as_view(),
|
||||
name='generate_certificate_exceptions'),
|
||||
|
||||
@@ -4,10 +4,12 @@ from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imp
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import gettext as _
|
||||
from rest_framework import serializers
|
||||
from .tools import get_student_from_identifier
|
||||
|
||||
from lms.djangoapps.certificates.models import CertificateStatuses
|
||||
from lms.djangoapps.instructor.access import ROLES
|
||||
|
||||
from .tools import get_student_from_identifier
|
||||
|
||||
|
||||
class RoleNameSerializer(serializers.Serializer): # pylint: disable=abstract-method
|
||||
"""
|
||||
@@ -230,6 +232,26 @@ class BlockDueDateSerializer(serializers.Serializer):
|
||||
self.fields['due_datetime'].required = False
|
||||
|
||||
|
||||
class CertificateStatusesSerializer(serializers.Serializer):
|
||||
"""
|
||||
Serializer for validating and serializing certificate status inputs.
|
||||
|
||||
This serializer is used to ensure that the provided certificate statuses
|
||||
conform to the predefined set of valid statuses defined in the
|
||||
`CertificateStatuses` enumeration.
|
||||
"""
|
||||
certificate_statuses = serializers.ListField(
|
||||
child=serializers.ChoiceField(choices=[
|
||||
CertificateStatuses.downloadable,
|
||||
CertificateStatuses.error,
|
||||
CertificateStatuses.notpassing,
|
||||
CertificateStatuses.audit_passing,
|
||||
CertificateStatuses.audit_notpassing,
|
||||
]),
|
||||
allow_empty=False # Set to True if you want to allow empty lists
|
||||
)
|
||||
|
||||
|
||||
class CertificateSerializer(serializers.Serializer):
|
||||
"""
|
||||
Serializer for multiple operations related with certificates.
|
||||
|
||||
Reference in New Issue
Block a user