feat: upgrade change_due date to drf ( 16th ) (#35392)
* feat: upgrading simple api to drf compatible.
This commit is contained in:
@@ -4160,6 +4160,21 @@ class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
# This operation regenerates the cache, so we can use cached results from edx-when.
|
||||
assert get_date_for_block(self.course, self.week1, self.user1, use_cached=True) == due_date
|
||||
|
||||
def test_change_due_date_with_reason(self):
|
||||
url = reverse('change_due_date', kwargs={'course_id': str(self.course.id)})
|
||||
due_date = datetime.datetime(2013, 12, 30, tzinfo=UTC)
|
||||
response = self.client.post(url, {
|
||||
'student': self.user1.username,
|
||||
'url': str(self.week1.location),
|
||||
'due_datetime': '12/30/2013 00:00',
|
||||
'reason': 'Testing reason.' # this is optional field.
|
||||
})
|
||||
assert response.status_code == 200, response.content
|
||||
|
||||
assert get_extended_due(self.course, self.week1, self.user1) == due_date
|
||||
# This operation regenerates the cache, so we can use cached results from edx-when.
|
||||
assert get_date_for_block(self.course, self.week1, self.user1, use_cached=True) == due_date
|
||||
|
||||
def test_change_to_invalid_due_date(self):
|
||||
url = reverse('change_due_date', kwargs={'course_id': str(self.course.id)})
|
||||
response = self.client.post(url, {
|
||||
|
||||
@@ -107,8 +107,8 @@ from lms.djangoapps.instructor_task.api_helper import AlreadyRunningError, Queue
|
||||
from lms.djangoapps.instructor_task.data import InstructorTaskTypes
|
||||
from lms.djangoapps.instructor_task.models import ReportStore
|
||||
from lms.djangoapps.instructor.views.serializer import (
|
||||
AccessSerializer, RoleNameSerializer, ShowStudentExtensionSerializer,
|
||||
UserSerializer, SendEmailSerializer, StudentAttemptsSerializer
|
||||
AccessSerializer, BlockDueDateSerializer, RoleNameSerializer, ShowStudentExtensionSerializer, UserSerializer,
|
||||
SendEmailSerializer, StudentAttemptsSerializer
|
||||
)
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort, is_course_cohorted
|
||||
@@ -2967,28 +2967,50 @@ def _display_unit(unit):
|
||||
return str(unit.location)
|
||||
|
||||
|
||||
@handle_dashboard_error
|
||||
@require_POST
|
||||
@ensure_csrf_cookie
|
||||
@cache_control(no_cache=True, no_store=True, must_revalidate=True)
|
||||
@require_course_permission(permissions.GIVE_STUDENT_EXTENSION)
|
||||
@require_post_params('student', 'url', 'due_datetime')
|
||||
def change_due_date(request, course_id):
|
||||
@method_decorator(cache_control(no_cache=True, no_store=True, must_revalidate=True), name='dispatch')
|
||||
class ChangeDueDate(APIView):
|
||||
"""
|
||||
Grants a due date extension to a student for a particular unit.
|
||||
"""
|
||||
course = get_course_by_id(CourseKey.from_string(course_id))
|
||||
student = require_student_from_identifier(request.POST.get('student'))
|
||||
unit = find_unit(course, request.POST.get('url'))
|
||||
due_date = parse_datetime(request.POST.get('due_datetime'))
|
||||
reason = strip_tags(request.POST.get('reason', ''))
|
||||
permission_classes = (IsAuthenticated, permissions.InstructorPermission)
|
||||
permission_name = permissions.GIVE_STUDENT_EXTENSION
|
||||
serializer_class = BlockDueDateSerializer
|
||||
|
||||
set_due_date_extension(course, unit, student, due_date, request.user, reason=reason)
|
||||
@method_decorator(ensure_csrf_cookie)
|
||||
def post(self, request, course_id):
|
||||
"""
|
||||
Grants a due date extension to a student for a particular unit.
|
||||
|
||||
return JsonResponse(_(
|
||||
'Successfully changed due date for student {0} for {1} '
|
||||
'to {2}').format(student.profile.name, _display_unit(unit),
|
||||
due_date.strftime('%Y-%m-%d %H:%M')))
|
||||
params:
|
||||
url (str): The URL related to the block that needs the due date update.
|
||||
due_datetime (str): The new due date and time for the block.
|
||||
student (str): The email or username of the student whose access is being modified.
|
||||
"""
|
||||
serializer_data = self.serializer_class(data=request.data)
|
||||
if not serializer_data.is_valid():
|
||||
return HttpResponseBadRequest(reason=serializer_data.errors)
|
||||
|
||||
student = serializer_data.validated_data.get('student')
|
||||
if not student:
|
||||
response_payload = {
|
||||
'error': f'Could not find student matching identifier: {request.data.get("student")}'
|
||||
}
|
||||
return JsonResponse(response_payload)
|
||||
|
||||
course = get_course_by_id(CourseKey.from_string(course_id))
|
||||
|
||||
unit = find_unit(course, serializer_data.validated_data.get('url'))
|
||||
due_date = parse_datetime(serializer_data.validated_data.get('due_datetime'))
|
||||
reason = strip_tags(serializer_data.validated_data.get('reason', ''))
|
||||
try:
|
||||
set_due_date_extension(course, unit, student, due_date, request.user, reason=reason)
|
||||
except Exception as error: # pylint: disable=broad-except
|
||||
return JsonResponse({'error': str(error)}, status=400)
|
||||
|
||||
return JsonResponse(_(
|
||||
'Successfully changed due date for student {0} for {1} '
|
||||
'to {2}').format(student.profile.name, _display_unit(unit),
|
||||
due_date.strftime('%Y-%m-%d %H:%M')))
|
||||
|
||||
|
||||
@handle_dashboard_error
|
||||
|
||||
@@ -49,8 +49,8 @@ urlpatterns = [
|
||||
path('list_email_content', api.ListEmailContent.as_view(), name='list_email_content'),
|
||||
path('list_forum_members', api.list_forum_members, name='list_forum_members'),
|
||||
path('update_forum_role_membership', api.update_forum_role_membership, name='update_forum_role_membership'),
|
||||
path('change_due_date', api.ChangeDueDate.as_view(), name='change_due_date'),
|
||||
path('send_email', api.SendEmail.as_view(), name='send_email'),
|
||||
path('change_due_date', api.change_due_date, name='change_due_date'),
|
||||
path('reset_due_date', api.reset_due_date, name='reset_due_date'),
|
||||
path('show_unit_extensions', api.show_unit_extensions, name='show_unit_extensions'),
|
||||
path('show_student_extensions', api.ShowStudentExtensions.as_view(), name='show_student_extensions'),
|
||||
|
||||
@@ -149,3 +149,32 @@ class SendEmailSerializer(serializers.Serializer):
|
||||
subject = serializers.CharField(max_length=128, write_only=True, required=True)
|
||||
message = serializers.CharField(required=True)
|
||||
schedule = serializers.CharField(required=False)
|
||||
|
||||
|
||||
class BlockDueDateSerializer(serializers.Serializer):
|
||||
"""
|
||||
Serializer for handling block due date updates for a specific student.
|
||||
Fields:
|
||||
url (str): The URL related to the block that needs the due date update.
|
||||
due_datetime (str): The new due date and time for the block.
|
||||
student (str): The email or username of the student whose access is being modified.
|
||||
reason (str): Reason why updating this.
|
||||
"""
|
||||
url = serializers.CharField()
|
||||
due_datetime = serializers.CharField()
|
||||
student = serializers.CharField(
|
||||
max_length=255,
|
||||
help_text="Email or username of user to change access"
|
||||
)
|
||||
reason = serializers.CharField(required=False)
|
||||
|
||||
def validate_student(self, value):
|
||||
"""
|
||||
Validate that the student corresponds to an existing user.
|
||||
"""
|
||||
try:
|
||||
user = get_student_from_identifier(value)
|
||||
except User.DoesNotExist:
|
||||
return None
|
||||
|
||||
return user
|
||||
|
||||
Reference in New Issue
Block a user