diff --git a/edx_when/migrations/0009_contentdate_assignment_title_contentdate_course_name_and_more.py b/edx_when/migrations/0009_contentdate_assignment_title_contentdate_course_name_and_more.py new file mode 100644 index 00000000..ad87bcf7 --- /dev/null +++ b/edx_when/migrations/0009_contentdate_assignment_title_contentdate_course_name_and_more.py @@ -0,0 +1,46 @@ +# Generated by Django 4.2.22 on 2025-08-20 09:11 + +import opaque_keys.edx.django.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('edx_when', '0008_courseversion_block_type'), + ] + + operations = [ + migrations.AddField( + model_name='contentdate', + name='assignment_title', + field=models.CharField(blank=True, db_index=True, default='', max_length=255), + ), + migrations.AddField( + model_name='contentdate', + name='course_name', + field=models.CharField(blank=True, default='', max_length=255), + ), + migrations.AddField( + model_name='contentdate', + name='subsection_name', + field=models.CharField(blank=True, db_index=True, default='', max_length=255), + ), + migrations.AddField( + model_name='userdate', + name='first_component_block_id', + field=opaque_keys.edx.django.models.UsageKeyField(blank=True, db_index=True, max_length=255, null=True), + ), + migrations.AddIndex( + model_name='contentdate', + index=models.Index(fields=['assignment_title', 'course_id'], name='edx_when_assignment_course_idx'), + ), + migrations.AddIndex( + model_name='contentdate', + index=models.Index(fields=['subsection_name', 'course_id'], name='edx_when_subsection_course_idx'), + ), + migrations.AddIndex( + model_name='userdate', + index=models.Index(fields=['user', 'first_component_block_id'], name='edx_when_user_first_block_idx'), + ), + ] diff --git a/edx_when/models.py b/edx_when/models.py index e540bdfa..55653cfa 100644 --- a/edx_when/models.py +++ b/edx_when/models.py @@ -93,6 +93,9 @@ class ContentDate(models.Model): field = models.CharField(max_length=255, default='') active = models.BooleanField(default=True) block_type = models.CharField(max_length=255, null=True) + assignment_title = models.CharField(max_length=255, blank=True, default='', db_index=True) + course_name = models.CharField(max_length=255, blank=True, default='') + subsection_name = models.CharField(max_length=255, blank=True, default='', db_index=True) class Meta: """Django Metadata.""" @@ -100,6 +103,8 @@ class Meta: unique_together = ('policy', 'location', 'field') indexes = [ models.Index(fields=('course_id', 'block_type'), name='edx_when_course_block_type_idx'), + models.Index(fields=('assignment_title', 'course_id'), name='edx_when_assignment_course_idx'), + models.Index(fields=('subsection_name', 'course_id'), name='edx_when_subsection_course_idx'), ] def __str__(self): @@ -109,6 +114,14 @@ def __str__(self): # Location already holds course id return f'ContentDate({self.policy}, {self.location}, {self.field}, {self.block_type})' + def __repr__(self): + """ + Get a detailed representation of this model instance. + """ + return (f'ContentDate(id={self.id}, assignment_title="{self.assignment_title}", ' + f'course_name="{self.course_name}", subsection_name="{self.subsection_name}", ' + f'policy={self.policy}, location={self.location})') + class UserDate(TimeStampedModel): """ @@ -125,6 +138,14 @@ class UserDate(TimeStampedModel): actor = models.ForeignKey( get_user_model(), null=True, default=None, blank=True, related_name="actor", on_delete=models.CASCADE ) + first_component_block_id = UsageKeyField(null=True, blank=True, max_length=255, db_index=True) + + class Meta: + """Django Metadata.""" + + indexes = [ + models.Index(fields=('user', 'first_component_block_id'), name='edx_when_user_first_block_idx'), + ] @property def actual_date(self): @@ -169,3 +190,12 @@ def __str__(self): # Location already holds course id # pylint: disable=no-member return f'{self.user.username}, {self.content_date.location}, {self.content_date.field}' + + def __repr__(self): + """ + Get a detailed representation of this model instance. + """ + # pylint: disable=no-member + return (f'UserDate(id={self.id}, user="{self.user.username}", ' + f'first_component_block_id={self.first_component_block_id}, ' + f'content_date={self.content_date.id})')