Skip to content

Commit

Permalink
feat: Optimize the querying of course block dates when querying dates…
Browse files Browse the repository at this point in the history
… for use in a

course outline, which don't need block dates below the subsection level of a course.
Also, rework the block date caching to use TieredCache, as well as using the current
published version of a course in the cache key to remove the need for cache invalidation.

TNL-8061
  • Loading branch information
Julia Eskew committed Aug 31, 2021
1 parent 3ef2751 commit 3d16a0e
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 109 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ Change Log
Unreleased
~~~~~~~~~~

[2.2.0] - 2021-08-27
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Added optimization when requesting course block dates for an outline, where block dates below subsections are unneeded.
* Use current version of the course to improve the cache key, along with using the TieredCache to cache date data.

[2.1.0] - 2021-07-23
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Added Django 3.2 Support
Expand Down
4 changes: 2 additions & 2 deletions edx_when/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Your project description goes here.
Central source of course block dates for the LMS.
"""

__version__ = '2.1.0'
__version__ = '2.2.0'

default_app_config = 'edx_when.apps.EdxWhenConfig' # pylint: disable=invalid-name
192 changes: 132 additions & 60 deletions edx_when/api.py

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions edx_when/migrations/0008_courseversion_block_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Generated by Django 3.2.6 on 2021-08-31 13:55

import django.db.models.deletion
import opaque_keys.edx.django.models
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('edx_when', '0007_meta_tweaks'),
]

operations = [
migrations.CreateModel(
name='CourseVersion',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('published_version', models.CharField(max_length=255)),
],
),
migrations.AddField(
model_name='contentdate',
name='block_type',
field=models.CharField(max_length=255, null=True),
),
migrations.AlterField(
model_name='contentdate',
name='course_id',
field=opaque_keys.edx.django.models.CourseKeyField(max_length=255),
),
migrations.AlterField(
model_name='contentdate',
name='location',
field=opaque_keys.edx.django.models.UsageKeyField(default=None, max_length=255, null=True),
),
migrations.AddIndex(
model_name='contentdate',
index=models.Index(fields=['course_id', 'block_type'], name='edx_when_course_block_type_idx'),
),
migrations.AddIndex(
model_name='contentdate',
index=models.Index(fields=['course_id'], name='edx_when_course_id_idx'),
),
migrations.AddIndex(
model_name='contentdate',
index=models.Index(fields=['location'], name='edx_when_location_idx'),
),
migrations.AddField(
model_name='contentdate',
name='course_version',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='edx_when.courseversion'),
),
]
23 changes: 20 additions & 3 deletions edx_when/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,30 +84,47 @@ def clean(self):
raise ValidationError(_("Absolute and relative dates cannot both be used"))


class CourseVersion(models.Model):
"""
Stores published versions of a course. Used to more easily cache the block dates.
.. no_pii:
"""

published_version = models.CharField(max_length=255, blank=False)


class ContentDate(models.Model):
"""
Ties a DatePolicy to a specific piece of course content. (e.g. a due date for a homework).
.. no_pii:
"""

course_id = CourseKeyField(db_index=True, max_length=255)
course_id = CourseKeyField(max_length=255)
policy = models.ForeignKey(DatePolicy, on_delete=models.CASCADE)
location = UsageKeyField(null=True, default=None, db_index=True, max_length=255)
location = UsageKeyField(null=True, default=None, max_length=255)
field = models.CharField(max_length=255, default='')
active = models.BooleanField(default=True)
block_type = models.CharField(max_length=255, null=True)
course_version = models.ForeignKey(CourseVersion, null=True, on_delete=models.CASCADE)

class Meta:
"""Django Metadata."""

unique_together = ('policy', 'location', 'field')
indexes = [
models.Index(fields=('course_id', 'block_type'), name='edx_when_course_block_type_idx'),
models.Index(fields=['course_id'], name='edx_when_course_id_idx'),
models.Index(fields=['location'], name='edx_when_location_idx'),
]

def __str__(self):
"""
Get a string representation of this model instance.
"""
# Location already holds course id
return f'{self.location}, {self.field}'
return f'ContentDate({self.policy}, {self.location}, {self.field}, {self.block_type})'

def schedule_for_user(self, user):
"""
Expand Down
Empty file added tests/__init__.py
Empty file.
Loading

0 comments on commit 3d16a0e

Please sign in to comment.