diff --git a/generic/admin.py b/generic/admin.py index 6954556a..6026ee07 100644 --- a/generic/admin.py +++ b/generic/admin.py @@ -2,14 +2,27 @@ from longs.models import Exam from django.contrib import admin # Register your models here. -from .models import Examination, Sign, Condition, Plane, Contrast, QuestionNote, NoteType -#from .models import Examination, Sign, Site, Condition +from .models import ( + Examination, + Sign, + Condition, + Plane, + Contrast, + QuestionNote, + NoteType, + CidUser, + CidUserExam, +) + +# from .models import Examination, Sign, Site, Condition admin.site.register(Examination) admin.site.register(Sign) -#admin.site.register(Site) +# admin.site.register(Site) admin.site.register(Condition) admin.site.register(Plane) admin.site.register(Contrast) admin.site.register(QuestionNote) admin.site.register(NoteType) +admin.site.register(CidUser) +admin.site.register(CidUserExam) diff --git a/generic/models.py b/generic/models.py index 92be98f9..5203d655 100644 --- a/generic/models.py +++ b/generic/models.py @@ -11,6 +11,7 @@ from django.conf import settings from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType + class Plane(models.Model): plane = models.CharField(max_length=200) @@ -18,7 +19,8 @@ class Plane(models.Model): return self.plane class Meta: - ordering = ('plane', ) + ordering = ("plane",) + class Contrast(models.Model): contrast = models.CharField(max_length=200) @@ -27,7 +29,8 @@ class Contrast(models.Model): return self.contrast class Meta: - ordering = ('contrast', ) + ordering = ("contrast",) + class Examination(models.Model): examination = models.CharField(max_length=200) @@ -36,7 +39,8 @@ class Examination(models.Model): return self.examination class Meta: - ordering = ('examination', ) + ordering = ("examination",) + class Site(models.Model): site = models.CharField(max_length=200) @@ -45,23 +49,26 @@ class Site(models.Model): def __str__(self): return self.site + class Condition(tagulous.models.TagModel): pass + class Sign(tagulous.models.TagModel): pass class ExamBase(models.Model): name = models.CharField(max_length=200, help_text="Name of the exam") - #exam_questions = SortedManyToManyField(Long, related_name="exams", blank="true") + # exam_questions = SortedManyToManyField(Long, related_name="exams", blank="true") active = models.BooleanField( help_text="If an exam should be available to take", default=False ) exam_mode = models.BooleanField( - help_text="If an exam should be taken in exam mode (users results will be submited to the server for marking)", default=False + help_text="If an exam should be taken in exam mode (users results will be submited to the server for marking)", + default=False, ) publish_results = models.BooleanField( @@ -73,19 +80,24 @@ class ExamBase(models.Model): ) json_creation_time = models.DateTimeField(blank=True, default=None, null=True) - exam_json_id = models.IntegerField(default=1, help_text="auto incrementing field when json recreated") - - archive = models.BooleanField(help_text="Archived exams will remain on the test system but will not be displayed by default", default=False) - - open_access = models.BooleanField( - help_text="If the exam is freely accessible (to view and edit on the test system)", default=False + exam_json_id = models.IntegerField( + default=1, help_text="auto incrementing field when json recreated" ) - #time_limit = models.IntegerField( + archive = models.BooleanField( + help_text="Archived exams will remain on the test system but will not be displayed by default", + default=False, + ) + + open_access = models.BooleanField( + help_text="If the exam is freely accessible (to view and edit on the test system)", + default=False, + ) + + # time_limit = models.IntegerField( # help_text="Exam time limit (in seconds). Default is 2100 secondse (35 minutes)", # default=2100, - #) - + # ) class Meta: abstract = True @@ -115,36 +127,47 @@ class ExamBase(models.Model): authors = [i for i in self.author.all()] return authors + class NoteType(models.Model): note_type = models.CharField(max_length=200) def __str__(self): return self.note_type + class QuestionNote(models.Model): content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() - question = GenericForeignKey('content_type', 'object_id') - #author = models.ForeignKey(User, + question = GenericForeignKey("content_type", "object_id") + # author = models.ForeignKey(User, author = models.CharField(max_length=200, blank=True) - user_author = models.ForeignKey( settings.AUTH_USER_MODEL, - on_delete=models.CASCADE, blank=True, null=True) + user_author = models.ForeignKey( + settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True + ) note = models.TextField(blank=True) created_on = models.DateTimeField(auto_now_add=True) complete = models.BooleanField(default=False) - note_type = models.ForeignKey(NoteType, on_delete=models.CASCADE, null=True, blank=True) + note_type = models.ForeignKey( + NoteType, on_delete=models.CASCADE, null=True, blank=True + ) - #def get_absolute_url(self): + # def get_absolute_url(self): # self.pk = self.rapid_id # return reverse('rapids:question_detail', kwargs={'pk': self.pk}) def __str__(self): - return "{}: {} [{}] {} / {}".format(self.content_type, self.get_author_str(), self.created_on, self.note_type, self.note) + return "{}: {} [{}] {} / {}".format( + self.content_type, + self.get_author_str(), + self.created_on, + self.note_type, + self.note, + ) def get_absolute_url(self): # TODO: return to question if logged in @@ -160,4 +183,19 @@ class QuestionNote(models.Model): return self.author def get_short_str(self): - return f"{self.note_type} - {self.note}" \ No newline at end of file + return f"{self.note_type} - {self.note}" + + +class CidUser(models.Model): + cid = models.IntegerField(blank=True, null=True) + passcode = models.CharField(blank=True, max_length=50) + +class CidUserExam(models.Model): + content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) + object_id = models.PositiveIntegerField() + question = GenericForeignKey("content_type", "object_id") + + start_time = models.DateTimeField(blank=True, null=True) + end_time = models.DateTimeField(blank=True, null=True) + + cid_user = models.ForeignKey(CidUser, on_delete=models.CASCADE) diff --git a/sbas/views.py b/sbas/views.py index a04b2827..a1c92955 100644 --- a/sbas/views.py +++ b/sbas/views.py @@ -86,7 +86,7 @@ def exam_scores_cid(request, pk): questions = exam.exam_questions.all() cids = ( - CidUserAnswer.objects.filter(question__in=questions) + CidUserAnswer.objects.filter(question__in=questions, exam__id=pk) .order_by("cid") .values_list("cid", flat=True) .distinct() @@ -106,7 +106,7 @@ def exam_scores_cid(request, pk): user_names[cid] = cid for q in questions: # Get user answer - s = q.cid_user_answers.filter(cid=cid).first() + s = q.cid_user_answers.filter(cid=cid, exam__id=pk).first() if not s: # skip if no answer user_answers_marks[cid].append(0)