switch to generic exam urls
This commit is contained in:
+127
-22
@@ -284,6 +284,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
cid_user_answer,
|
||||
app,
|
||||
question_type,
|
||||
normalise_score=None,
|
||||
):
|
||||
self.Exam = exam
|
||||
self.Question = question
|
||||
@@ -291,6 +292,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
self.CidUserAnswer = cid_user_answer
|
||||
self.app_name = app
|
||||
self.question_type = question_type
|
||||
self.normalise_score = normalise_score
|
||||
|
||||
# THis may be better than check_user_access below
|
||||
# group_map = {"rapids" : "rapid_checker", "anatomy" : "anatomy_checker", "longs":"long_checker"}
|
||||
@@ -562,7 +564,9 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_user(self, request, exam_id, user_id):
|
||||
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
|
||||
exam = get_object_or_404(
|
||||
self.Exam.objects.prefetch_related("author"), pk=exam_id
|
||||
)
|
||||
|
||||
if request.user not in exam.author.all():
|
||||
if not self.check_user_access(request.user, exam_id):
|
||||
@@ -573,10 +577,11 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
return JsonResponse(model_to_dict(user_exam))
|
||||
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_report_email_status(self, request, exam_id):
|
||||
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
|
||||
exam = get_object_or_404(
|
||||
self.Exam.objects.prefetch_related("author"), pk=exam_id
|
||||
)
|
||||
|
||||
if request.user not in exam.author.all():
|
||||
if not self.check_user_access(request.user, exam_id):
|
||||
@@ -600,20 +605,21 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
},
|
||||
)
|
||||
return JsonResponse(status)
|
||||
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_report_email_unsent(self, request, exam_id):
|
||||
return self.exam_report_email(request, exam_id, unsent_only=True)
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_report_email(self, request, exam_id, unsent_only=False, users=None):
|
||||
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
|
||||
exam = get_object_or_404(
|
||||
self.Exam.objects.prefetch_related("author"), pk=exam_id
|
||||
)
|
||||
|
||||
if request.user not in exam.author.all():
|
||||
if not self.check_user_access(request.user, exam_id):
|
||||
raise PermissionDenied
|
||||
|
||||
|
||||
additional_email = request.GET.get("additional_email", "")
|
||||
|
||||
# check addition email is valid
|
||||
@@ -639,9 +645,10 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
if json.loads(user_exam.results_emailed_status)[0] == True:
|
||||
continue
|
||||
|
||||
|
||||
if additional_email:
|
||||
email_results[user.pk] = exam.email_user_results(user, additional_emails=[additional_email])
|
||||
email_results[user.pk] = exam.email_user_results(
|
||||
user, additional_emails=[additional_email]
|
||||
)
|
||||
else:
|
||||
email_results[user.pk] = exam.email_user_results(user)
|
||||
email_results[user.pk].append(f"{time}")
|
||||
@@ -651,7 +658,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
exam.exam_results_emailed = time
|
||||
exam.save()
|
||||
|
||||
|
||||
return JsonResponse(email_results)
|
||||
|
||||
@method_decorator(login_required)
|
||||
@@ -660,24 +667,26 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
# print(Exam.objects.all())
|
||||
# exams = Exam.objects.all()
|
||||
# print("test", Exam.objects.all().get(id=pk))
|
||||
#exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
|
||||
# exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
|
||||
|
||||
#u = get_object_or_404(User, pk=user_id)
|
||||
# u = get_object_or_404(User, pk=user_id)
|
||||
|
||||
#if request.user not in exam.author.all():
|
||||
# if request.user not in exam.author.all():
|
||||
# if not self.check_user_access(request.user, exam_id):
|
||||
# raise PermissionDenied
|
||||
|
||||
#res = exam.email_user_results(u)
|
||||
# res = exam.email_user_results(u)
|
||||
|
||||
#return HttpResponse(res)
|
||||
# return HttpResponse(res)
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_user_report(self, request, exam_id, user_id):
|
||||
# print(Exam.objects.all())
|
||||
# exams = Exam.objects.all()
|
||||
# print("test", Exam.objects.all().get(id=pk))
|
||||
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=exam_id)
|
||||
exam = get_object_or_404(
|
||||
self.Exam.objects.prefetch_related("author"), pk=exam_id
|
||||
)
|
||||
|
||||
u = get_object_or_404(User, pk=user_id)
|
||||
|
||||
@@ -690,7 +699,6 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
return HttpResponse(res)
|
||||
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_overview(self, request, pk):
|
||||
# print(Exam.objects.all())
|
||||
@@ -698,7 +706,6 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
# print("test", Exam.objects.all().get(id=pk))
|
||||
exam = get_object_or_404(self.Exam.objects.prefetch_related("author"), pk=pk)
|
||||
|
||||
|
||||
if request.user not in exam.author.all():
|
||||
if not self.check_user_access(request.user, pk):
|
||||
raise PermissionDenied
|
||||
@@ -1517,6 +1524,103 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
return JsonResponse(question_json)
|
||||
|
||||
@method_decorator(login_required)
|
||||
def exam_scores_user(self, request, pk):
|
||||
return self.exam_scores_cid_user(request, pk)
|
||||
|
||||
def exam_scores_cid_user(self, request, pk, cid=None, passcode=""):
|
||||
exam = get_object_or_404(self.Exam, pk=pk)
|
||||
|
||||
if not exam.exam_mode:
|
||||
raise Http404("Packet not in exam mode")
|
||||
|
||||
# TODO:Need some kind of test for cid
|
||||
|
||||
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_q_map = {}
|
||||
|
||||
# for ans in cid_user_answers:
|
||||
# cid_user_answers_q_map[ans.question] = ans
|
||||
|
||||
answers_and_marks = []
|
||||
answers_marks = []
|
||||
answers = []
|
||||
|
||||
view_all_results = False
|
||||
if request.user.groups.filter(name="view_all_results").exists():
|
||||
view_all_results = True
|
||||
|
||||
for q in questions:
|
||||
# Get user answer
|
||||
if cid is not None:
|
||||
user_answer = q.cid_user_answers.filter(cid=cid, exam__id=pk).first()
|
||||
else:
|
||||
user_answer = q.cid_user_answers.filter(
|
||||
user=request.user, exam__id=pk
|
||||
).first()
|
||||
# user_answer = cid_user_answers_q_map[q]
|
||||
|
||||
if not user_answer or user_answer is None:
|
||||
# skip if no answer
|
||||
answers_marks.append(0)
|
||||
# answers.append("")
|
||||
answer_score = 0
|
||||
ans = "Not answered"
|
||||
else:
|
||||
if user_answer.normal:
|
||||
ans = "Normal"
|
||||
else:
|
||||
ans = user_answer.answer
|
||||
answer_score = user_answer.get_answer_score()
|
||||
|
||||
correct_answer = q.get_primary_answer()
|
||||
|
||||
if not exam.publish_results and not view_all_results:
|
||||
correct_answer = "*****"
|
||||
answer_score = 0
|
||||
answers.append(ans)
|
||||
answers_marks.append(answer_score)
|
||||
answers_and_marks.append((ans, answer_score, correct_answer))
|
||||
|
||||
if "unmarked" in answers_marks:
|
||||
answered = [i for i in answers_marks if type(i) == int]
|
||||
total_score = sum(answered)
|
||||
unmarked_number = len(answers_marks) - len(answered)
|
||||
total_score = "{} ({} unmarked)".format(total_score, unmarked_number)
|
||||
else:
|
||||
total_score = sum(answers_marks)
|
||||
|
||||
max_score = len(questions) * 2
|
||||
|
||||
template_context = {
|
||||
"exam": exam,
|
||||
"cid": cid,
|
||||
"passcode": passcode,
|
||||
"questions": questions,
|
||||
"answers": answers,
|
||||
"answers_marks": answers_marks,
|
||||
"total_score": total_score,
|
||||
"max_score": max_score,
|
||||
"answers_and_marks": answers_and_marks,
|
||||
"view_all_results": view_all_results,
|
||||
}
|
||||
|
||||
if self.normalise_score is not None:
|
||||
|
||||
normalised_score = self.normalise_score(total_score)
|
||||
template_context["normalised_score"] = normalised_score
|
||||
|
||||
return render(
|
||||
request,
|
||||
f"{self.app_name}/exam_scores_user.html",
|
||||
template_context,
|
||||
)
|
||||
|
||||
def exam_scores_cid(self, request, pk):
|
||||
exam = get_object_or_404(self.Exam, pk=pk)
|
||||
|
||||
@@ -1563,7 +1667,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
cids.add(cid)
|
||||
else:
|
||||
cid = f"u/{cid_user_answer.user.pk}"
|
||||
#cids_user_id_map[cid] = cid_user_answer.user.username
|
||||
# cids_user_id_map[cid] = cid_user_answer.user.username
|
||||
name = f"{cid_user_answer.user.first_name} {cid_user_answer.user.last_name}"
|
||||
if not name.strip():
|
||||
name = cid_user_answer.user.username
|
||||
@@ -1665,11 +1769,11 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
exam.stats_min = min(user_scores_list)
|
||||
exam.stats_max = max(user_scores_list)
|
||||
|
||||
#exam.stats_graph = fig_html
|
||||
# exam.stats_graph = fig_html
|
||||
|
||||
user_data = {}
|
||||
for u in cids:
|
||||
#uid = cids_user_id_map[u]
|
||||
# uid = cids_user_id_map[u]
|
||||
user_data[u] = {
|
||||
"score": user_scores[u],
|
||||
"normalised_score": user_scores_normalised[u],
|
||||
@@ -1680,7 +1784,6 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
user_data[u]["callstates"] = str(counted_callstates)
|
||||
user_answers_callstates_counted[u] = counted_callstates
|
||||
|
||||
|
||||
exam.user_scores = user_data
|
||||
|
||||
exam.save()
|
||||
@@ -1709,7 +1812,9 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
}
|
||||
|
||||
if self.app_name == "rapids":
|
||||
template_variables["user_answers_callstates"] = user_answers_callstates_counted
|
||||
template_variables[
|
||||
"user_answers_callstates"
|
||||
] = user_answers_callstates_counted
|
||||
|
||||
return render(
|
||||
request,
|
||||
|
||||
Reference in New Issue
Block a user