feat!: upgrade start_certificate_regeneration to drf ( 29 ) (#35599)

* feat!: upgrading api to DRF.
This commit is contained in:
Awais Qureshi
2024-12-02 17:08:01 +05:00
committed by GitHub
parent 3d5f4983c5
commit 81d4239117
4 changed files with 58 additions and 41 deletions

View File

@@ -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')

View File

@@ -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')

View File

@@ -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'),

View File

@@ -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.