From e49628558c9315c3f72bcb88a21b01f4c636bdaa Mon Sep 17 00:00:00 2001 From: Jansen Kantor Date: Wed, 3 Apr 2024 10:08:50 -0400 Subject: [PATCH] feat: add validation and actions to course reset django admins (#34453) * fix: course opt in course id should be unique * feat: add validation for opt in course id admin page * feat: admin action to mark audits as failed --- lms/djangoapps/support/admin.py | 26 +++++++++++++++---- .../migrations/0005_unique_course_id.py | 19 ++++++++++++++ lms/djangoapps/support/models.py | 2 +- 3 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 lms/djangoapps/support/migrations/0005_unique_course_id.py diff --git a/lms/djangoapps/support/admin.py b/lms/djangoapps/support/admin.py index 2b7fbc7b48..2fde5d3465 100644 --- a/lms/djangoapps/support/admin.py +++ b/lms/djangoapps/support/admin.py @@ -1,21 +1,32 @@ """ Django admins for support models """ +from django import forms from django.contrib import admin from lms.djangoapps.support.models import CourseResetCourseOptIn, CourseResetAudit +from openedx.core.lib.courses import clean_course_id + + +class CourseResetCourseOptInAdminForm(forms.ModelForm): + """ Form for the CourseResetCourseOptIn Django admin page """ + class Meta: + model = CourseResetCourseOptIn + fields = ['course_id', 'active'] + + def clean_course_id(self): + return clean_course_id(self) class CourseResetCourseOptInAdmin(admin.ModelAdmin): """ Django admin for CourseResetCourseOptIn model """ - list_display = ['course_id', 'active'] - fields = ['course_id', 'active', 'created', 'modified'] + form = CourseResetCourseOptInAdminForm + list_display = ['course_id', 'active', 'created', 'modified'] def get_readonly_fields(self, request, obj=None): """ Ensure that 'course_id' cannot be edited after creation. """ if obj: - return ['course_id', 'created', 'modified'] - else: - return ['created', 'modified'] + return ['course_id'] + return [] class CourseResetAuditAdmin(admin.ModelAdmin): @@ -33,6 +44,7 @@ class CourseResetAuditAdmin(admin.ModelAdmin): 'reset_by', 'comment' ] + actions = ['mark_failed'] def get_readonly_fields(self, request, obj=None): """ @@ -56,6 +68,10 @@ class CourseResetAuditAdmin(admin.ModelAdmin): def user(self, obj): return obj.course_enrollment.user + @admin.action(description="Fail selected reset attempts") + def mark_failed(self, request, queryset): + queryset.update(status=CourseResetAudit.CourseResetStatus.FAILED) + admin.site.register(CourseResetCourseOptIn, CourseResetCourseOptInAdmin) admin.site.register(CourseResetAudit, CourseResetAuditAdmin) diff --git a/lms/djangoapps/support/migrations/0005_unique_course_id.py b/lms/djangoapps/support/migrations/0005_unique_course_id.py new file mode 100644 index 0000000000..baf89bedc3 --- /dev/null +++ b/lms/djangoapps/support/migrations/0005_unique_course_id.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.10 on 2024-03-29 18:56 + +from django.db import migrations +import opaque_keys.edx.django.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('support', '0004_add_comment_field'), + ] + + operations = [ + migrations.AlterField( + model_name='courseresetcourseoptin', + name='course_id', + field=opaque_keys.edx.django.models.CourseKeyField(max_length=255, unique=True), + ), + ] diff --git a/lms/djangoapps/support/models.py b/lms/djangoapps/support/models.py index a899c9ac56..32df989eed 100644 --- a/lms/djangoapps/support/models.py +++ b/lms/djangoapps/support/models.py @@ -22,7 +22,7 @@ class CourseResetCourseOptIn(TimeStampedModel): """ Model that represents a course which has opted in to the course reset feature. """ - course_id = CourseKeyField(max_length=255) + course_id = CourseKeyField(max_length=255, unique=True) active = BooleanField() def __str__(self):