This commit is contained in:
Ross
2021-12-11 12:47:28 +00:00
parent 6647fb69b0
commit 1f474c262e
3 changed files with 78 additions and 27 deletions
+14 -1
View File
@@ -2,7 +2,18 @@ from longs.models import Exam
from django.contrib import admin from django.contrib import admin
# Register your models here. # Register your models here.
from .models import Examination, Sign, Condition, Plane, Contrast, QuestionNote, NoteType from .models import (
Examination,
Sign,
Condition,
Plane,
Contrast,
QuestionNote,
NoteType,
CidUser,
CidUserExam,
)
# from .models import Examination, Sign, Site, Condition # from .models import Examination, Sign, Site, Condition
admin.site.register(Examination) admin.site.register(Examination)
@@ -13,3 +24,5 @@ admin.site.register(Plane)
admin.site.register(Contrast) admin.site.register(Contrast)
admin.site.register(QuestionNote) admin.site.register(QuestionNote)
admin.site.register(NoteType) admin.site.register(NoteType)
admin.site.register(CidUser)
admin.site.register(CidUserExam)
+51 -13
View File
@@ -11,6 +11,7 @@ from django.conf import settings
from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
class Plane(models.Model): class Plane(models.Model):
plane = models.CharField(max_length=200) plane = models.CharField(max_length=200)
@@ -18,7 +19,8 @@ class Plane(models.Model):
return self.plane return self.plane
class Meta: class Meta:
ordering = ('plane', ) ordering = ("plane",)
class Contrast(models.Model): class Contrast(models.Model):
contrast = models.CharField(max_length=200) contrast = models.CharField(max_length=200)
@@ -27,7 +29,8 @@ class Contrast(models.Model):
return self.contrast return self.contrast
class Meta: class Meta:
ordering = ('contrast', ) ordering = ("contrast",)
class Examination(models.Model): class Examination(models.Model):
examination = models.CharField(max_length=200) examination = models.CharField(max_length=200)
@@ -36,7 +39,8 @@ class Examination(models.Model):
return self.examination return self.examination
class Meta: class Meta:
ordering = ('examination', ) ordering = ("examination",)
class Site(models.Model): class Site(models.Model):
site = models.CharField(max_length=200) site = models.CharField(max_length=200)
@@ -45,9 +49,11 @@ class Site(models.Model):
def __str__(self): def __str__(self):
return self.site return self.site
class Condition(tagulous.models.TagModel): class Condition(tagulous.models.TagModel):
pass pass
class Sign(tagulous.models.TagModel): class Sign(tagulous.models.TagModel):
pass pass
@@ -61,7 +67,8 @@ class ExamBase(models.Model):
) )
exam_mode = models.BooleanField( 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( publish_results = models.BooleanField(
@@ -73,12 +80,18 @@ class ExamBase(models.Model):
) )
json_creation_time = models.DateTimeField(blank=True, default=None, null=True) 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") 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) 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( open_access = models.BooleanField(
help_text="If the exam is freely accessible (to view and edit on the test system)", default=False help_text="If the exam is freely accessible (to view and edit on the test system)",
default=False,
) )
# time_limit = models.IntegerField( # time_limit = models.IntegerField(
@@ -86,7 +99,6 @@ class ExamBase(models.Model):
# default=2100, # default=2100,
# ) # )
class Meta: class Meta:
abstract = True abstract = True
@@ -115,36 +127,47 @@ class ExamBase(models.Model):
authors = [i for i in self.author.all()] authors = [i for i in self.author.all()]
return authors return authors
class NoteType(models.Model): class NoteType(models.Model):
note_type = models.CharField(max_length=200) note_type = models.CharField(max_length=200)
def __str__(self): def __str__(self):
return self.note_type return self.note_type
class QuestionNote(models.Model): class QuestionNote(models.Model):
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField() object_id = models.PositiveIntegerField()
question = GenericForeignKey('content_type', 'object_id') question = GenericForeignKey("content_type", "object_id")
# author = models.ForeignKey(User, # author = models.ForeignKey(User,
author = models.CharField(max_length=200, blank=True) author = models.CharField(max_length=200, blank=True)
user_author = models.ForeignKey( settings.AUTH_USER_MODEL, user_author = models.ForeignKey(
on_delete=models.CASCADE, blank=True, null=True) settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True
)
note = models.TextField(blank=True) note = models.TextField(blank=True)
created_on = models.DateTimeField(auto_now_add=True) created_on = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False) 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 # self.pk = self.rapid_id
# return reverse('rapids:question_detail', kwargs={'pk': self.pk}) # return reverse('rapids:question_detail', kwargs={'pk': self.pk})
def __str__(self): 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): def get_absolute_url(self):
# TODO: return to question if logged in # TODO: return to question if logged in
@@ -161,3 +184,18 @@ class QuestionNote(models.Model):
def get_short_str(self): def get_short_str(self):
return f"{self.note_type} - {self.note}" 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)
+2 -2
View File
@@ -86,7 +86,7 @@ def exam_scores_cid(request, pk):
questions = exam.exam_questions.all() questions = exam.exam_questions.all()
cids = ( cids = (
CidUserAnswer.objects.filter(question__in=questions) CidUserAnswer.objects.filter(question__in=questions, exam__id=pk)
.order_by("cid") .order_by("cid")
.values_list("cid", flat=True) .values_list("cid", flat=True)
.distinct() .distinct()
@@ -106,7 +106,7 @@ def exam_scores_cid(request, pk):
user_names[cid] = cid user_names[cid] = cid
for q in questions: for q in questions:
# Get user answer # 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: if not s:
# skip if no answer # skip if no answer
user_answers_marks[cid].append(0) user_answers_marks[cid].append(0)