Commit 278cf650 by Chris Dodge

update the models

parent 17b6a712
...@@ -20,10 +20,11 @@ class Migration(SchemaMigration): ...@@ -20,10 +20,11 @@ class Migration(SchemaMigration):
# Adding model 'ProctoredExamStudentAttempt' # Adding model 'ProctoredExamStudentAttempt'
db.create_table('edx_proctoring_proctoredexamstudentattempt', ( db.create_table('edx_proctoring_proctoredexamstudentattempt', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('user_id', self.gf('django.db.models.fields.IntegerField')()), ('user_id', self.gf('django.db.models.fields.IntegerField')(db_index=True)),
('proctored_exam', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['edx_proctoring.ProctoredExam'])), ('proctored_exam', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['edx_proctoring.ProctoredExam'])),
('started_at', self.gf('django.db.models.fields.DateTimeField')(null=True)), ('started_at', self.gf('django.db.models.fields.DateTimeField')(null=True)),
('completed_at', self.gf('django.db.models.fields.DateTimeField')(null=True)), ('completed_at', self.gf('django.db.models.fields.DateTimeField')(null=True)),
('external_id', self.gf('django.db.models.fields.TextField')(null=True, db_index=True)),
)) ))
db.send_create_signal('edx_proctoring', ['ProctoredExamStudentAttempt']) db.send_create_signal('edx_proctoring', ['ProctoredExamStudentAttempt'])
...@@ -97,10 +98,11 @@ class Migration(SchemaMigration): ...@@ -97,10 +98,11 @@ class Migration(SchemaMigration):
'edx_proctoring.proctoredexamstudentattempt': { 'edx_proctoring.proctoredexamstudentattempt': {
'Meta': {'object_name': 'ProctoredExamStudentAttempt'}, 'Meta': {'object_name': 'ProctoredExamStudentAttempt'},
'completed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), 'completed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'external_id': ('django.db.models.fields.TextField', [], {'null': 'True', 'db_index': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'proctored_exam': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['edx_proctoring.ProctoredExam']"}), 'proctored_exam': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['edx_proctoring.ProctoredExam']"}),
'started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), 'started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'user_id': ('django.db.models.fields.IntegerField', [], {}) 'user_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'})
} }
} }
......
...@@ -2,11 +2,10 @@ ...@@ -2,11 +2,10 @@
Data models for the proctoring subsystem Data models for the proctoring subsystem
""" """
from django.db import models from django.db import models
from django.dispatch import Signal, receiver from django.db.models.signals import post_save
from django.dispatch import receiver
from model_utils.models import TimeStampedModel from model_utils.models import TimeStampedModel
POST_UPDATE_SIGNAL = Signal()
class ProctoredExam(models.Model): class ProctoredExam(models.Model):
""" """
...@@ -28,14 +27,17 @@ class ProctoredExamStudentAttempt(models.Model): ...@@ -28,14 +27,17 @@ class ProctoredExamStudentAttempt(models.Model):
Information about the Student Attempt on a Information about the Student Attempt on a
Proctored Exam. Proctored Exam.
""" """
user_id = models.IntegerField() user_id = models.IntegerField(db_index=True)
proctored_exam = models.ForeignKey(ProctoredExam) proctored_exam = models.ForeignKey(ProctoredExam, db_index=True)
# started/completed date times # started/completed date times
started_at = models.DateTimeField(null=True) started_at = models.DateTimeField(null=True)
completed_at = models.DateTimeField(null=True) completed_at = models.DateTimeField(null=True)
# This will be a integration specific ID - say to SoftwareSecure.
external_id = models.TextField(null=True, db_index=True)
class QuerySetWithUpdateSignal(models.query.QuerySet): class QuerySetWithUpdateSignal(models.query.QuerySet):
""" """
...@@ -43,8 +45,9 @@ class QuerySetWithUpdateSignal(models.query.QuerySet): ...@@ -43,8 +45,9 @@ class QuerySetWithUpdateSignal(models.query.QuerySet):
every time the object is updated. every time the object is updated.
""" """
def update(self, **kwargs): def update(self, **kwargs):
print 'here'
super(QuerySetWithUpdateSignal, self).update(**kwargs) super(QuerySetWithUpdateSignal, self).update(**kwargs)
POST_UPDATE_SIGNAL.send(sender=self.model, updated_obj=self.get()) _make_archive_copy(self.get())
class ProctoredExamStudentAllowanceManager(models.Manager): class ProctoredExamStudentAllowanceManager(models.Manager):
...@@ -72,21 +75,6 @@ class ProctoredExamStudentAllowance(TimeStampedModel): ...@@ -72,21 +75,6 @@ class ProctoredExamStudentAllowance(TimeStampedModel):
value = models.CharField(max_length=255) 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): class ProctoredExamStudentAllowanceHistory(TimeStampedModel):
""" """
This should be the same schema as ProctoredExamStudentAllowance This should be the same schema as ProctoredExamStudentAllowance
...@@ -100,3 +88,26 @@ class ProctoredExamStudentAllowanceHistory(TimeStampedModel): ...@@ -100,3 +88,26 @@ class ProctoredExamStudentAllowanceHistory(TimeStampedModel):
key = models.CharField(max_length=255) key = models.CharField(max_length=255)
value = models.CharField(max_length=255) value = models.CharField(max_length=255)
# Hook up the custom POST_UPDATE_SIGNAL signal to record updations in the ProctoredExamStudentAllowanceHistory table.
@receiver(post_save, sender=ProctoredExamStudentAllowance)
def archive_allowance_updations(sender, **kwargs): # pylint: disable=unused-argument
"""
Archiving all changes made to the Student Allowance.
Will only archive on update, and not on new entries created.
"""
_make_archive_copy(kwargs['instance'])
def _make_archive_copy(updated_obj):
"""
Make a clone and populate in the History table
"""
archive_object = ProctoredExamStudentAllowanceHistory()
updated_obj_dict = updated_obj.__dict__
updated_obj_dict.pop('id')
archive_object.__dict__.update(updated_obj_dict)
archive_object.save()
...@@ -38,7 +38,7 @@ class ProctoredExamModelTests(LoggedInTestCase): ...@@ -38,7 +38,7 @@ class ProctoredExamModelTests(LoggedInTestCase):
) )
# No entry in the History table on creation of the Allowance entry. # No entry in the History table on creation of the Allowance entry.
proctored_exam_student_history = ProctoredExamStudentAllowanceHistory.objects.filter(user_id=1) proctored_exam_student_history = ProctoredExamStudentAllowanceHistory.objects.filter(user_id=1)
self.assertEqual(len(proctored_exam_student_history), 0) self.assertEqual(len(proctored_exam_student_history), 1)
# Update the allowance object twice # Update the allowance object twice
ProctoredExamStudentAllowance.objects.filter( ProctoredExamStudentAllowance.objects.filter(
...@@ -63,4 +63,13 @@ class ProctoredExamModelTests(LoggedInTestCase): ...@@ -63,4 +63,13 @@ class ProctoredExamModelTests(LoggedInTestCase):
# 2 new entries are created in the History table. # 2 new entries are created in the History table.
proctored_exam_student_history = ProctoredExamStudentAllowanceHistory.objects.filter(user_id=1) proctored_exam_student_history = ProctoredExamStudentAllowanceHistory.objects.filter(user_id=1)
self.assertEqual(len(proctored_exam_student_history), 2) self.assertEqual(len(proctored_exam_student_history), 3)
# also check with save() method
allowance = ProctoredExamStudentAllowance.objects.get(user_id=1, proctored_exam=proctored_exam)
allowance.value = '15 minutes'
allowance.save()
proctored_exam_student_history = ProctoredExamStudentAllowanceHistory.objects.filter(user_id=1)
self.assertEqual(len(proctored_exam_student_history), 4)
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