Add exam scores user template with dynamic answer display and feedback
This commit is contained in:
+5
-1
@@ -146,6 +146,9 @@ import plotly.express as px
|
|||||||
from django.db.models import Prefetch
|
from django.db.models import Prefetch
|
||||||
|
|
||||||
|
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
|
||||||
class RedirectMixin:
|
class RedirectMixin:
|
||||||
def get_success_url(self) -> str:
|
def get_success_url(self) -> str:
|
||||||
if "redirect" in self.request.GET:
|
if "redirect" in self.request.GET:
|
||||||
@@ -2329,6 +2332,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
if not exam.publish_results and not view_all_results:
|
if not exam.publish_results and not view_all_results:
|
||||||
correct_answer = "*****"
|
correct_answer = "*****"
|
||||||
answer_score = 0
|
answer_score = 0
|
||||||
|
logger.debug(f"{ans=} {answer_score=} {correct_answer=}")
|
||||||
answers.append(ans)
|
answers.append(ans)
|
||||||
answers_marks.append(answer_score)
|
answers_marks.append(answer_score)
|
||||||
|
|
||||||
@@ -2345,7 +2349,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
case "physics":
|
case "physics":
|
||||||
total_score = sum(sum(i) for i in answers_marks)
|
total_score = sum(sum(i) for i in answers_marks)
|
||||||
case _:
|
case _:
|
||||||
if "unmarked" in answers_marks:
|
if "unmarked" in answers_marks or None in answers_marks:
|
||||||
answered = [i for i in answers_marks if type(i) == int]
|
answered = [i for i in answers_marks if type(i) == int]
|
||||||
total_score = sum(answered)
|
total_score = sum(answered)
|
||||||
unmarked_number = len(answers_marks) - len(answered)
|
unmarked_number = len(answers_marks) - len(answered)
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="question-display-block">
|
||||||
|
<div class="hide-show">HIDE/SHOW</div>
|
||||||
|
<div class="inner-display-block">
|
||||||
|
Question <span class="question-number">1</span>
|
||||||
|
<div id="single-dicom-viewer" class="dicom-viewer" data-images="" data-annotations=''>
|
||||||
|
</div>
|
||||||
|
<div class="feedback"></div>
|
||||||
|
<div>
|
||||||
|
<details>
|
||||||
|
<summary>Answers:</summary><span class="answers"></span>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="shorts">
|
||||||
|
{% include 'user_score_header.html' %}
|
||||||
|
<ul class="score-answer-list">
|
||||||
|
{% for ans, score, correct_answer in answers_and_marks %}
|
||||||
|
<li class="user-answer-li" data-question-number="{{forloop.counter}}">Question {{forloop.counter}} - Correct answer: {% if exam.publish_results %}<span class="correct-answer">{{correct_answer}}</span>{% endif %}
|
||||||
|
<span class="view-question-link" data-qn={{forloop.counter0}}>View</span>
|
||||||
|
<br/>
|
||||||
|
<span class="user-answer-score user-answer-score-{{score}}">
|
||||||
|
<span class="submitted-user-answer">
|
||||||
|
<pre>{{ans}}</pre>
|
||||||
|
</span>
|
||||||
|
{% if exam.publish_results or view_all_results%}
|
||||||
|
<span class="answer-score">Score: {{score}}</span>
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% include 'user_scores_footer.html' %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% block js %}
|
||||||
|
<script>
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$(".hide-show").click((evt, el) => {
|
||||||
|
$(".inner-display-block").toggle();
|
||||||
|
})
|
||||||
|
|
||||||
|
$(".view-question-link").on("click", function (e) {
|
||||||
|
console.log("click", e)
|
||||||
|
question_number = e.currentTarget.dataset.qn;
|
||||||
|
$("#single-dicom-viewer").empty();
|
||||||
|
$.ajax({
|
||||||
|
url: `{% url 'shorts:question_review' pk=exam.pk %}`,
|
||||||
|
data: {
|
||||||
|
csrfmiddlewaretoken: "{{ csrf_token }}",
|
||||||
|
question_number: question_number
|
||||||
|
},
|
||||||
|
type: "POST",
|
||||||
|
dataType: "json",
|
||||||
|
})
|
||||||
|
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
|
||||||
|
.done(function (data) {
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
let images = data.images
|
||||||
|
|
||||||
|
if ("feedback_images" in data) {
|
||||||
|
images.push(...data.feedback_images)
|
||||||
|
}
|
||||||
|
|
||||||
|
let event = new CustomEvent('loadDicomViewerUrls', {
|
||||||
|
"detail": { "images": images, "annotations": data.annotations }
|
||||||
|
});
|
||||||
|
|
||||||
|
window.dispatchEvent(event);
|
||||||
|
$(".question-display-block .answers").empty().append(data.answers.toString());
|
||||||
|
n = parseInt(question_number) + 1
|
||||||
|
$(".question-display-block .question-number").empty().append(n);
|
||||||
|
$(".question-display-block .feedback").empty().append(`Feedback: ${data.feedback}<br />`);
|
||||||
|
// show some message according to the response.
|
||||||
|
// For eg. A message box showing that the status has been changed
|
||||||
|
$(".inner-display-block").show();
|
||||||
|
})
|
||||||
|
.always(function () {
|
||||||
|
console.log('[Done]');
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
$(".view-question-link").first().click();
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block css %}
|
||||||
|
<style>
|
||||||
|
.answer-score {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
{% endblock css %}
|
||||||
|
|
||||||
Reference in New Issue
Block a user