Commit 17b6a712 by Afzal Wali

Created a custom POST_UPDATE_SIGNAL to save archive all updations to the Allowance object.

parent 7e3944e8
......@@ -2,10 +2,11 @@
Data models for the proctoring subsystem
"""
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.dispatch import Signal, receiver
from model_utils.models import TimeStampedModel
POST_UPDATE_SIGNAL = Signal()
class ProctoredExam(models.Model):
"""
......@@ -36,11 +37,32 @@ class ProctoredExamStudentAttempt(models.Model):
completed_at = models.DateTimeField(null=True)
class QuerySetWithUpdateSignal(models.query.QuerySet):
"""
Custom QuerySet class to send the POST_UPDATE_SIGNAL
every time the object is updated.
"""
def update(self, **kwargs):
super(QuerySetWithUpdateSignal, self).update(**kwargs)
POST_UPDATE_SIGNAL.send(sender=self.model, updated_obj=self.get())
class ProctoredExamStudentAllowanceManager(models.Manager):
"""
Custom manager to override with the custom queryset
to enable the POST_UPDATE_SIGNAL
"""
def get_query_set(self):
return QuerySetWithUpdateSignal(self.model, using=self._db)
class ProctoredExamStudentAllowance(TimeStampedModel):
"""
Information about allowing a student additional time on exam.
"""
objects = ProctoredExamStudentAllowanceManager()
user_id = models.IntegerField()
proctored_exam = models.ForeignKey(ProctoredExam)
......@@ -50,6 +72,21 @@ class ProctoredExamStudentAllowance(TimeStampedModel):
value = models.CharField(max_length=255)
# Hook up the custom POST_UPDATE_SIGNAL signal to record updations in the ProctoredExamStudentAllowanceHistory table.
@receiver(POST_UPDATE_SIGNAL, sender=ProctoredExamStudentAllowance)
def archive_allowance_updations(sender, updated_obj, **kwargs): # pylint: disable=unused-argument
"""
Archiving all changes made to the Student Allowance.
Will only archive on updation, and not on new entries created.
"""
archive_object = ProctoredExamStudentAllowanceHistory()
updated_obj_dict = updated_obj.__dict__
updated_obj_dict.pop('id')
archive_object.__dict__.update(updated_obj_dict)
archive_object.save()
class ProctoredExamStudentAllowanceHistory(TimeStampedModel):
"""
This should be the same schema as ProctoredExamStudentAllowance
......@@ -63,14 +100,3 @@ class ProctoredExamStudentAllowanceHistory(TimeStampedModel):
key = models.CharField(max_length=255)
value = models.CharField(max_length=255)
# Hook up Django signals to record changes in the ProctoredExamStudentAllowanceHistory table.
@receiver(post_save, sender=ProctoredExamStudentAllowance)
def archive_deleted_user_notification(sender, instance, *args, **kwargs): # pylint: disable=unused-argument
"""
Archiving the deleted user notifications.
"""
archive_object = ProctoredExamStudentAllowanceHistory()
archive_object.__dict__.update(instance.__dict__)
archive_object.save()
......@@ -21,8 +21,9 @@ class ProctoredExamModelTests(LoggedInTestCase):
def test_save_proctored_exam_student_allowance_history(self): # pylint: disable=invalid-name
"""
Test to Save the proctored Exam Student Allowance object
which also saves the entry in the History Table.
Test to Save and update the proctored Exam Student Allowance object.
Upon first save, a new entry is _not_ created in the History table
However, a new entry in the History table is created every time the Student Allowance entry is updated.
"""
proctored_exam = ProctoredExam.objects.create(
course_id='test_course',
......@@ -32,8 +33,34 @@ class ProctoredExamModelTests(LoggedInTestCase):
ProctoredExamStudentAllowance.objects.create(
user_id=1,
proctored_exam=proctored_exam,
key='test_key',
value='test_val'
key='allowance_key',
value='20 minutes'
)
# No entry in the History table on creation of the Allowance entry.
proctored_exam_student_history = ProctoredExamStudentAllowanceHistory.objects.filter(user_id=1)
self.assertEqual(len(proctored_exam_student_history), 1)
self.assertEqual(len(proctored_exam_student_history), 0)
# Update the allowance object twice
ProctoredExamStudentAllowance.objects.filter(
user_id=1,
proctored_exam=proctored_exam,
).update(
user_id=1,
proctored_exam=proctored_exam,
key='allowance_key update 1',
value='10 minutes'
)
ProctoredExamStudentAllowance.objects.filter(
user_id=1,
proctored_exam=proctored_exam,
).update(
user_id=1,
proctored_exam=proctored_exam,
key='allowance_key update 2',
value='5 minutes'
)
# 2 new entries are created in the History table.
proctored_exam_student_history = ProctoredExamStudentAllowanceHistory.objects.filter(user_id=1)
self.assertEqual(len(proctored_exam_student_history), 2)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment