from django.contrib.contenttypes.fields import GenericRelation from django.db import models from django.utils import timezone from django.core.files.storage import FileSystemStorage from django.conf import settings from django.utils.html import format_html from django.urls import reverse from django.utils.translation import ugettext_lazy as _ from sortedm2m.fields import SortedManyToManyField from generic.models import ExamBase, QuestionNote import reversion class Category(models.Model): category = models.CharField(max_length=200) def __str__(self): return self.category class Question(models.Model): stem = models.TextField( blank=False, help_text="Stem of the question", ) answer_help_text = "Answer (check for true, uncheck for false)" a = models.TextField( blank=False, help_text="The question text", ) a_answer = models.BooleanField( help_text=answer_help_text, default=True ) a_feedback = models.TextField( blank=True, help_text="Feedback for answer", ) b = models.TextField( blank=False, help_text="The question text", ) b_answer = models.BooleanField( help_text=answer_help_text, default=True ) b_feedback = models.TextField( blank=True, help_text="Feedback for answer", ) c = models.TextField( blank=False, help_text="The question text", ) c_answer = models.BooleanField( help_text=answer_help_text, default=True ) c_feedback = models.TextField( blank=True, help_text="Feedback for answer", ) d = models.TextField( blank=False, help_text="The question text", ) d_answer = models.BooleanField( help_text=answer_help_text, default=True ) d_feedback = models.TextField( blank=True, help_text="Feedback for answer", ) e = models.TextField( blank=False, help_text="The question text", ) e_answer = models.BooleanField( help_text=answer_help_text, default=True ) e_feedback = models.TextField( blank=True, help_text="Feedback for answer", ) created_date = models.DateTimeField(default=timezone.now) author = models.ManyToManyField( settings.AUTH_USER_MODEL, blank=True, help_text="Author(s) of question", related_name="physics_authored_questions", ) category = models.ForeignKey( Category, on_delete=models.SET_NULL, null=True, blank=True ) notes = GenericRelation(QuestionNote) def __str__(self): return self.stem def clean(self): if self.a: self.a = self.a.strip() if self.b: self.b = self.b.strip() if self.c: self.c = self.c.strip() if self.d: self.d = self.d.strip() if self.e: self.e = self.e.strip() def get_absolute_url(self): return reverse("physics:question_detail", kwargs={"pk": self.pk}) def get_answers(self): return (self.a_answer, self.b_answer, self.c_answer, self.d_answer, self.e_answer) def get_questions(self): return (self.a, self.b, self.c, self.d, self.e) @reversion.register class Exam(ExamBase): app_name = "rapids" exam_questions = SortedManyToManyField( Question, related_name="exams", blank="true" ) time_limit = models.IntegerField( help_text="Exam time limit (in seconds)", blank=True, null=True, ) recreate_json = None author = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, help_text='Author of exam', related_name="physics_exam_author") @reversion.register class CidUserAnswer(models.Model): """User answers by candidate""" question = models.ForeignKey( Question, related_name="cid_user_answers", on_delete=models.CASCADE ) a = models.BooleanField(blank=False) b = models.BooleanField(blank=False) c = models.BooleanField(blank=False) d = models.BooleanField(blank=False) e = models.BooleanField(blank=False) cid = models.IntegerField(blank=True, null=True) # Each user answer is associated with a particular exam exam = models.ForeignKey( Exam, related_name="cid_user_answers", on_delete=models.CASCADE, null=True ) created = models.DateTimeField(auto_now_add=True) updated = models.DateTimeField(auto_now=True) def __str__(self): return "{}/{}/{}".format(self.cid, self.exam, self.question.pk) def get_answers(self): return (self.a, self.b, self.c, self.d, self.e) def get_answer_scores(self): q = self.question if self.a == q.a_answer: score_a = 1 else: score_a = 0 if self.b == q.b_answer: score_b = 1 else: score_b = 0 if self.c == q.c_answer: score_c = 1 else: score_c = 0 if self.d == q.d_answer: score_d = 1 else: score_d = 0 if self.e == q.e_answer: score_e = 1 else: score_e = 0 return (score_a, score_b, score_c, score_d, score_e)