shorts might now be functional?
This commit is contained in:
+101
-9
@@ -30,6 +30,7 @@ from django.utils.html import mark_safe
|
||||
from rapids.models import Abnormality, Examination, Region
|
||||
|
||||
from helpers.images import get_image_hash, image_as_base64
|
||||
from django.utils.html import format_html
|
||||
|
||||
|
||||
def image_directory_path(instance, filename):
|
||||
@@ -63,6 +64,12 @@ class Question(QuestionBase):
|
||||
related_name="shorts_authored_questions",
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return "{}: {}".format(
|
||||
self.id,
|
||||
self.history,
|
||||
)
|
||||
|
||||
def get_app_name(self):
|
||||
return "shorts"
|
||||
|
||||
@@ -116,6 +123,52 @@ class Question(QuestionBase):
|
||||
def get_best_sample_answer(self):
|
||||
return self.sample_answers.filter(score__gt=0).order_by("-score").first()
|
||||
|
||||
def get_exams(self):
|
||||
e = self.exams.all().values_list("name", flat=True)
|
||||
exams = ", ".join(e)
|
||||
return exams
|
||||
|
||||
def get_unmarked_user_answer_string(self, exam_pk: int = None):
|
||||
unmarked_answers = self.get_unmarked_user_answers(exam_pk)
|
||||
|
||||
if not unmarked_answers:
|
||||
return "No answers to mark"
|
||||
return format_html(
|
||||
"<span class='warn'>{} answer unmarked:</span> {}".format(
|
||||
len(unmarked_answers), ", ".join(unmarked_answers)
|
||||
)
|
||||
)
|
||||
|
||||
def get_unmarked_user_answers(self, exam_pk: int | None = None, marker=None):
|
||||
if exam_pk is None:
|
||||
user_answer_queryset = self.cid_user_answers.all()
|
||||
else:
|
||||
user_answer_queryset = self.cid_user_answers.filter(exam__id=exam_pk)
|
||||
|
||||
unmarked_answers = user_answer_queryset.filter(score__isnull=True)
|
||||
|
||||
|
||||
return unmarked_answers
|
||||
|
||||
|
||||
def get_unmarked_user_answer_count(self, exam_pk=None, marker=None):
|
||||
if exam_pk is None:
|
||||
return self.cid_user_answers.all().count()
|
||||
|
||||
return len(self.get_unmarked_user_answers(exam_pk, marker=marker))
|
||||
|
||||
def get_user_answers(self, exam_pk=None, include_normal=True):
|
||||
if exam_pk is None:
|
||||
queryset = self.cid_user_answers.all()
|
||||
else:
|
||||
queryset = self.cid_user_answers.filter(exam__id=exam_pk)
|
||||
|
||||
if not include_normal:
|
||||
queryset = queryset.filter(normal=False)
|
||||
|
||||
user_answers = set([i.answer for i in queryset])
|
||||
|
||||
return user_answers
|
||||
|
||||
|
||||
class QuestionImage(models.Model):
|
||||
@@ -230,6 +283,10 @@ class Exam(ExamBase):
|
||||
related_name="shorts_exam_markers",
|
||||
)
|
||||
|
||||
double_mark = models.BooleanField(
|
||||
default=False, help_text="Defines if an exam is expected to be double marked"
|
||||
)
|
||||
|
||||
valid_cid_users = models.ManyToManyField(
|
||||
CidUser, blank=True, related_name="shorts_exams"
|
||||
)
|
||||
@@ -271,20 +328,16 @@ class Exam(ExamBase):
|
||||
return "shorts"
|
||||
|
||||
def get_exam_json(self, based=True):
|
||||
# TODO
|
||||
|
||||
return {}
|
||||
questions = self.get_questions()
|
||||
|
||||
exam_questions = defaultdict(dict)
|
||||
|
||||
exam_order = []
|
||||
|
||||
q: Rapid
|
||||
q: Question
|
||||
for q in questions:
|
||||
exam_order.append(q.id)
|
||||
|
||||
# Loop through rapidimage associations
|
||||
images = []
|
||||
feedback_images = []
|
||||
image_titles = []
|
||||
@@ -311,7 +364,7 @@ class Exam(ExamBase):
|
||||
"images": images,
|
||||
# "feedback_image": [],
|
||||
# "annotations": [str(q.image_annotations)],
|
||||
"type": "rapid",
|
||||
"type": "short",
|
||||
}
|
||||
|
||||
if not self.exam_mode:
|
||||
@@ -331,9 +384,9 @@ class Exam(ExamBase):
|
||||
# exam_questions[q.id]["feedback_image"] = feedback_images
|
||||
|
||||
exam_json = {
|
||||
"eid": "rapid/{}".format(self.id),
|
||||
"eid": "short/{}".format(self.id),
|
||||
"cached": False,
|
||||
"exam_type": "rapid",
|
||||
"exam_type": "short",
|
||||
"exam_name": self.name,
|
||||
"exam_mode": self.exam_mode,
|
||||
"exam_order": exam_order,
|
||||
@@ -343,6 +396,7 @@ class Exam(ExamBase):
|
||||
if self.time_limit:
|
||||
exam_json["exam_time"] = self.time_limit
|
||||
|
||||
print(exam_json)
|
||||
return exam_json
|
||||
|
||||
def get_absolute_url(self):
|
||||
@@ -373,8 +427,13 @@ class UserAnswer(UserAnswerBase):
|
||||
Exam, related_name="cid_user_answers", on_delete=models.CASCADE, null=True
|
||||
)
|
||||
|
||||
# If score is null then the answer is unmarked
|
||||
score = models.IntegerField(
|
||||
default=0, blank=True, validators=[MinValueValidator(0), MaxValueValidator(5)]
|
||||
default=0, blank=True, validators=[MinValueValidator(0), MaxValueValidator(5)], null=True
|
||||
)
|
||||
|
||||
candidate_feedback = models.TextField(
|
||||
null=True, blank=True, help_text="Feedback for the candidate"
|
||||
)
|
||||
|
||||
class CallStateOptions(models.TextChoices):
|
||||
@@ -426,6 +485,15 @@ class UserAnswer(UserAnswerBase):
|
||||
def get_answer_score(self, cached=True):
|
||||
return self.score
|
||||
|
||||
def get_answer_string(self):
|
||||
return self.answer
|
||||
|
||||
def is_marked(self):
|
||||
if self.score is None:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class QuestionFinding(FindingBase):
|
||||
question = models.ForeignKey(
|
||||
@@ -439,3 +507,27 @@ class QuestionFinding(FindingBase):
|
||||
def __str__(self) -> str:
|
||||
findings = self.findings.all().values_list("name")
|
||||
return f"Findings: {self.question.id}/{findings}/{self.description}"
|
||||
|
||||
class AnswerMarks(models.Model):
|
||||
# Same as in UserAnswer except null is not allowed
|
||||
score = models.IntegerField(
|
||||
default=0, blank=True, validators=[MinValueValidator(0), MaxValueValidator(5)]
|
||||
)
|
||||
|
||||
mark_reason = models.TextField(
|
||||
null=True,
|
||||
blank=True,
|
||||
help_text="Reason for the given mark - not visible to candidates",
|
||||
)
|
||||
|
||||
marker = models.ForeignKey(
|
||||
settings.AUTH_USER_MODEL, related_name="shorts_answers", on_delete=models.CASCADE
|
||||
)
|
||||
|
||||
user_answer = models.ForeignKey(
|
||||
UserAnswer,
|
||||
related_name="mark",
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user