.
This commit is contained in:
+12
-6
@@ -42,7 +42,12 @@ import json
|
|||||||
import statistics
|
import statistics
|
||||||
import plotly.express as px
|
import plotly.express as px
|
||||||
|
|
||||||
from generic.views import AuthorRequiredMixin, ExamCloneMixin, ExamViews, GenericViewBase
|
from generic.views import (
|
||||||
|
AuthorRequiredMixin,
|
||||||
|
ExamCloneMixin,
|
||||||
|
ExamViews,
|
||||||
|
GenericViewBase,
|
||||||
|
)
|
||||||
|
|
||||||
from rest_framework import viewsets, permissions
|
from rest_framework import viewsets, permissions
|
||||||
from rest_framework.pagination import PageNumberPagination
|
from rest_framework.pagination import PageNumberPagination
|
||||||
@@ -311,7 +316,7 @@ def exam_take(request, pk, sk, cid, passcode):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#def loadJsonAnswer(answer):
|
# def loadJsonAnswer(answer):
|
||||||
# # As access is not restricted make sure the data appears valid
|
# # As access is not restricted make sure the data appears valid
|
||||||
# if (not isinstance(answer["cid"], int)) or (not isinstance(answer["eid"], int)):
|
# if (not isinstance(answer["cid"], int)) or (not isinstance(answer["eid"], int)):
|
||||||
# return False, JsonResponse({"success": False, "error": "invalid"})
|
# return False, JsonResponse({"success": False, "error": "invalid"})
|
||||||
@@ -368,9 +373,7 @@ def exam_take(request, pk, sk, cid, passcode):
|
|||||||
# return True, None
|
# return True, None
|
||||||
|
|
||||||
|
|
||||||
GenericExamViews = ExamViews(
|
GenericExamViews = ExamViews(Exam, Question, None, CidUserAnswer, "physics", "physics")
|
||||||
Exam, Question, None, CidUserAnswer, "physics", "physics"
|
|
||||||
)
|
|
||||||
|
|
||||||
GenericViews = GenericViewBase("physics", Question, CidUserAnswer, Exam)
|
GenericViews = GenericViewBase("physics", Question, CidUserAnswer, Exam)
|
||||||
|
|
||||||
@@ -391,10 +394,13 @@ class ExamClone(AuthorOrCheckerRequiredMixin, ExamCloneMixin, ExamCreate):
|
|||||||
"""Clone exam view"""
|
"""Clone exam view"""
|
||||||
|
|
||||||
|
|
||||||
class ExamAuthorUpdate(RevisionMixin, LoginRequiredMixin, AuthorRequiredMixin, UpdateView):
|
class ExamAuthorUpdate(
|
||||||
|
RevisionMixin, LoginRequiredMixin, AuthorRequiredMixin, UpdateView
|
||||||
|
):
|
||||||
model = Exam
|
model = Exam
|
||||||
form_class = ExamAuthorForm
|
form_class = ExamAuthorForm
|
||||||
|
|
||||||
|
|
||||||
class ExamDelete(RevisionMixin, AuthorOrCheckerRequiredMixin, DeleteView):
|
class ExamDelete(RevisionMixin, AuthorOrCheckerRequiredMixin, DeleteView):
|
||||||
model = Exam
|
model = Exam
|
||||||
template_name = "exam_confirm_delete.html"
|
template_name = "exam_confirm_delete.html"
|
||||||
|
|||||||
+27
-16
@@ -42,7 +42,12 @@ from .models import (
|
|||||||
CidUserAnswer,
|
CidUserAnswer,
|
||||||
)
|
)
|
||||||
|
|
||||||
from generic.views import AuthorRequiredMixin, ExamCloneMixin, ExamViews, GenericViewBase
|
from generic.views import (
|
||||||
|
AuthorRequiredMixin,
|
||||||
|
ExamCloneMixin,
|
||||||
|
ExamViews,
|
||||||
|
GenericViewBase,
|
||||||
|
)
|
||||||
|
|
||||||
from reversion.views import RevisionMixin
|
from reversion.views import RevisionMixin
|
||||||
|
|
||||||
@@ -350,8 +355,8 @@ class RapidUpdate(
|
|||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
# save exam orders (there must be a better way to do this)
|
# save exam orders (there must be a better way to do this)
|
||||||
#exam_orders = {}
|
# exam_orders = {}
|
||||||
#for exam in self.object.exams.all():
|
# for exam in self.object.exams.all():
|
||||||
# exam_orders[exam] = list(exam.exam_questions.all())
|
# exam_orders[exam] = list(exam.exam_questions.all())
|
||||||
|
|
||||||
self.object = form.save(commit=False)
|
self.object = form.save(commit=False)
|
||||||
@@ -371,8 +376,8 @@ class RapidUpdate(
|
|||||||
answer_formset.save()
|
answer_formset.save()
|
||||||
|
|
||||||
# restore exam orders
|
# restore exam orders
|
||||||
#wanted_exams = form["exams"].data
|
# wanted_exams = form["exams"].data
|
||||||
#for exam in self.object.exams.all():
|
# for exam in self.object.exams.all():
|
||||||
# if exam in exam_orders and self.object in exam_orders[exam]:
|
# if exam in exam_orders and self.object in exam_orders[exam]:
|
||||||
# print(exam_orders[exam])
|
# print(exam_orders[exam])
|
||||||
# exam.exam_questions.set(exam_orders[exam])
|
# exam.exam_questions.set(exam_orders[exam])
|
||||||
@@ -509,7 +514,6 @@ class RapidView(LoginRequiredMixin, SingleTableMixin, FilterView):
|
|||||||
filterset_class = RapidFilter
|
filterset_class = RapidFilter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def mark_all(request, exam_pk, sk):
|
def mark_all(request, exam_pk, sk):
|
||||||
return mark(request, exam_pk, sk, unmarked_exam_answers_only=False)
|
return mark(request, exam_pk, sk, unmarked_exam_answers_only=False)
|
||||||
@@ -673,7 +677,6 @@ def mark(request, exam_pk, sk, unmarked_exam_answers_only=True, review=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def exam_scores_cid_user(request, pk, cid, passcode):
|
def exam_scores_cid_user(request, pk, cid, passcode):
|
||||||
exam = get_object_or_404(Exam, pk=pk)
|
exam = get_object_or_404(Exam, pk=pk)
|
||||||
|
|
||||||
@@ -682,13 +685,15 @@ def exam_scores_cid_user(request, pk, cid, passcode):
|
|||||||
|
|
||||||
# TODO:Need some kind of test for cid
|
# TODO:Need some kind of test for cid
|
||||||
|
|
||||||
questions = exam.exam_questions.all()#.prefetch_related("cid_user_answers", "answers")
|
questions = (
|
||||||
|
exam.exam_questions.all()
|
||||||
|
) # .prefetch_related("cid_user_answers", "answers")
|
||||||
|
|
||||||
#cid_user_answers = list(CidUserAnswer.objects.filter(cid=cid, exam__id=pk).prefetch_related("question"))
|
# cid_user_answers = list(CidUserAnswer.objects.filter(cid=cid, exam__id=pk).prefetch_related("question"))
|
||||||
|
|
||||||
#cid_user_answers_q_map = {}
|
# cid_user_answers_q_map = {}
|
||||||
|
|
||||||
#for ans in cid_user_answers:
|
# for ans in cid_user_answers:
|
||||||
# cid_user_answers_q_map[ans.question] = ans
|
# cid_user_answers_q_map[ans.question] = ans
|
||||||
|
|
||||||
answers_and_marks = []
|
answers_and_marks = []
|
||||||
@@ -702,7 +707,7 @@ def exam_scores_cid_user(request, pk, cid, passcode):
|
|||||||
for q in questions:
|
for q in questions:
|
||||||
# Get user answer
|
# Get user answer
|
||||||
user_answer = q.cid_user_answers.filter(cid=cid, exam__id=pk).first()
|
user_answer = q.cid_user_answers.filter(cid=cid, exam__id=pk).first()
|
||||||
#user_answer = cid_user_answers_q_map[q]
|
# user_answer = cid_user_answers_q_map[q]
|
||||||
|
|
||||||
if not user_answer or user_answer is None:
|
if not user_answer or user_answer is None:
|
||||||
# skip if no answer
|
# skip if no answer
|
||||||
@@ -762,9 +767,7 @@ class QuestionDelete(AuthorOrCheckerRequiredMixin, DeleteView):
|
|||||||
success_url = reverse_lazy("rapids:rapid_view")
|
success_url = reverse_lazy("rapids:rapid_view")
|
||||||
|
|
||||||
|
|
||||||
GenericExamViews = ExamViews(
|
GenericExamViews = ExamViews(Exam, Rapid, Answer, CidUserAnswer, "rapids", "rapid")
|
||||||
Exam, Rapid, Answer, CidUserAnswer, "rapids", "rapid"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ExamCreate(RevisionMixin, LoginRequiredMixin, CreateView):
|
class ExamCreate(RevisionMixin, LoginRequiredMixin, CreateView):
|
||||||
@@ -793,18 +796,24 @@ class ExamUpdate(
|
|||||||
|
|
||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
class ExamAuthorUpdate(RevisionMixin, LoginRequiredMixin, AuthorRequiredMixin, UpdateView):
|
|
||||||
|
class ExamAuthorUpdate(
|
||||||
|
RevisionMixin, LoginRequiredMixin, AuthorRequiredMixin, UpdateView
|
||||||
|
):
|
||||||
model = Exam
|
model = Exam
|
||||||
form_class = ExamAuthorForm
|
form_class = ExamAuthorForm
|
||||||
|
|
||||||
|
|
||||||
class ExamDelete(RevisionMixin, AuthorOrCheckerRequiredMixin, DeleteView):
|
class ExamDelete(RevisionMixin, AuthorOrCheckerRequiredMixin, DeleteView):
|
||||||
model = Exam
|
model = Exam
|
||||||
template_name = "exam_confirm_delete.html"
|
template_name = "exam_confirm_delete.html"
|
||||||
success_url = reverse_lazy("rapids:index")
|
success_url = reverse_lazy("rapids:index")
|
||||||
|
|
||||||
|
|
||||||
class UserAnswerView(LoginRequiredMixin, DetailView):
|
class UserAnswerView(LoginRequiredMixin, DetailView):
|
||||||
model = CidUserAnswer
|
model = CidUserAnswer
|
||||||
|
|
||||||
|
|
||||||
class UserAnswerTableView(LoginRequiredMixin, SingleTableMixin, FilterView):
|
class UserAnswerTableView(LoginRequiredMixin, SingleTableMixin, FilterView):
|
||||||
model = CidUserAnswer
|
model = CidUserAnswer
|
||||||
table_class = RapidUserAnswerTable
|
table_class = RapidUserAnswerTable
|
||||||
@@ -921,6 +930,7 @@ class RapidLateralityViewSet(
|
|||||||
|
|
||||||
GenericViews = GenericViewBase("rapids", Rapid, CidUserAnswer, Exam)
|
GenericViews = GenericViewBase("rapids", Rapid, CidUserAnswer, Exam)
|
||||||
|
|
||||||
|
|
||||||
@user_is_author_or_rapid_checker
|
@user_is_author_or_rapid_checker
|
||||||
def question_anonymise_dicom(request, pk):
|
def question_anonymise_dicom(request, pk):
|
||||||
question = get_object_or_404(Rapid, pk=pk)
|
question = get_object_or_404(Rapid, pk=pk)
|
||||||
@@ -929,6 +939,7 @@ def question_anonymise_dicom(request, pk):
|
|||||||
|
|
||||||
return redirect("rapids:question_detail", pk=pk)
|
return redirect("rapids:question_detail", pk=pk)
|
||||||
|
|
||||||
|
|
||||||
@user_is_author_or_rapid_checker
|
@user_is_author_or_rapid_checker
|
||||||
def question_save_annotation(request, pk):
|
def question_save_annotation(request, pk):
|
||||||
if request.is_ajax() and request.method == "POST":
|
if request.is_ajax() and request.method == "POST":
|
||||||
|
|||||||
Reference in New Issue
Block a user