feat: add db models for course reset feature (#34282)

* feat: add db models for course reset feature

* style: quality

* fix: read only fields when creating / updating model
This commit is contained in:
Jansen Kantor
2024-02-23 11:56:04 -05:00
committed by GitHub
parent 78afee7573
commit ab4f62777c
3 changed files with 141 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
""" Django admins for support models """
from django.contrib import admin
from lms.djangoapps.support.models import CourseResetCourseOptIn, CourseResetAudit
class CourseResetCourseOptInAdmin(admin.ModelAdmin):
""" Django admin for CourseResetCourseOptIn model """
list_display = ['course_id', 'active']
fields = ['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']
class CourseResetAuditAdmin(admin.ModelAdmin):
""" Django admin for CourseResetAudit model """
list_display = ['course', 'user', 'status', 'created', 'completed_at', 'reset_by']
fields = ['created', 'modified', 'status', 'completed_at', 'course', 'user', 'course_enrollment', 'reset_by']
def get_readonly_fields(self, request, obj=None):
"""
If we are editing an existing model, we should only be able to change the status, for potential debugging
"""
if obj:
return ['created', 'modified', 'completed_at', 'course', 'user', 'course_enrollment', 'reset_by']
else:
return ['created', 'modified', 'user']
@admin.display(description="user")
def user(self, obj):
return obj.course_enrollment.user
admin.site.register(CourseResetCourseOptIn, CourseResetCourseOptInAdmin)
admin.site.register(CourseResetAudit, CourseResetAuditAdmin)

View File

@@ -0,0 +1,49 @@
# Generated by Django 3.2.23 on 2024-02-22 14:48
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import model_utils.fields
import opaque_keys.edx.django.models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('student', '0045_auto_20230808_0944'),
('support', '0002_alter_historicalusersocialauth_options'),
]
operations = [
migrations.CreateModel(
name='CourseResetCourseOptIn',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('course_id', opaque_keys.edx.django.models.CourseKeyField(max_length=255)),
('active', models.BooleanField()),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='CourseResetAudit',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('status', models.CharField(choices=[('in_progress', 'In Progress'), ('complete', 'Complete'), ('enqueued', 'Enqueued'), ('failed', 'Failed')], default='enqueued', max_length=12)),
('completed_at', models.DateTimeField(blank=True, default=None, null=True)),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='support.courseresetcourseoptin')),
('course_enrollment', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='student.courseenrollment')),
('reset_by', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)),
],
options={
'abstract': False,
},
),
]

View File

@@ -1,9 +1,59 @@
"""
Models used to implement support related models in such as SSO History model
"""
from django.contrib.auth import get_user_model
from django.db.models import ForeignKey, DO_NOTHING, CASCADE, TextChoices
from django.db.models.fields import BooleanField, CharField, DateTimeField
from model_utils.models import TimeStampedModel
from opaque_keys.edx.django.models import CourseKeyField
from simple_history import register
from social_django.models import UserSocialAuth
from common.djangoapps.student.models import CourseEnrollment
User = get_user_model()
# Registers UserSocialAuth with simple-django-history.
register(UserSocialAuth, app=__package__)
class CourseResetCourseOptIn(TimeStampedModel):
"""
Model that represents a course which has opted in to the course reset feature.
"""
course_id = CourseKeyField(max_length=255)
active = BooleanField()
def __str__(self):
return f'{self.course_id} - {"ACTIVE" if self.active else "INACTIVE"}'
class CourseResetAudit(TimeStampedModel):
"""
Model which records the course reset action's status and metadata
"""
class CourseResetStatus(TextChoices):
IN_PROGRESS = "in_progress"
COMPLETE = "complete"
ENQUEUED = "enqueued"
FAILED = "failed"
course = ForeignKey(
CourseResetCourseOptIn,
on_delete=CASCADE
)
course_enrollment = ForeignKey(
CourseEnrollment,
on_delete=DO_NOTHING
)
reset_by = ForeignKey(
User,
on_delete=DO_NOTHING
)
status = CharField(
max_length=12,
choices=CourseResetStatus.choices,
default=CourseResetStatus.ENQUEUED,
)
completed_at = DateTimeField(default=None, null=True, blank=True)