allow resenting of exam answers
This commit is contained in:
@@ -58,7 +58,7 @@
|
|||||||
hx-post="{% url 'atlas:collection_reset_answers' collection.pk %}"
|
hx-post="{% url 'atlas:collection_reset_answers' collection.pk %}"
|
||||||
>Reset all answers</button>
|
>Reset all answers</button>
|
||||||
|
|
||||||
</summary>
|
</details>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include 'exam_overview_js.html' %}
|
{% include 'exam_overview_js.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
+1
-1
@@ -2835,7 +2835,7 @@ def collection_reset_answers(request, exam_id: int):
|
|||||||
collection.exam_user_status.all().delete()
|
collection.exam_user_status.all().delete()
|
||||||
|
|
||||||
# CidUserExams
|
# CidUserExams
|
||||||
collection.cid_users.delete()
|
collection.cid_users.all().delete()
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -36,6 +36,23 @@ Exam mode: {{ exam.exam_mode }}<br />
|
|||||||
{% if exam.exam_mode %}
|
{% if exam.exam_mode %}
|
||||||
Cid candidates: <a href="{{exam.get_cid_edit_url}}">{{candidate_count.0}}</a>, User candidates: <a href="{{exam.get_user_edit_url}}">{{candidate_count.1}}</a><br />
|
Cid candidates: <a href="{{exam.get_cid_edit_url}}">{{candidate_count.0}}</a>, User candidates: <a href="{{exam.get_user_edit_url}}">{{candidate_count.1}}</a><br />
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Answer management</summary>
|
||||||
|
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<p>Manage answers for this collection. </p>
|
||||||
|
|
||||||
|
Please note these are permanant and cannot be undone.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button title="This will clear all user answers and attempts"
|
||||||
|
hx-post="{% url exam.get_app_name|add:':exam_reset_answers' exam.pk %}"
|
||||||
|
hx-swap="outerHTML"
|
||||||
|
>Reset all answers</button>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
Open access: {{ exam.open_access }}<br />
|
Open access: {{ exam.open_access }}<br />
|
||||||
|
|
||||||
{% if exam.start_date %}
|
{% if exam.start_date %}
|
||||||
@@ -66,3 +83,5 @@ Open access: {{ exam.open_access }}<br />
|
|||||||
Author(s): {% for author in exam.author.all %}
|
Author(s): {% for author in exam.author.all %}
|
||||||
{{ author }}{% if not forloop.last %}, {% endif %}
|
{{ author }}{% if not forloop.last %}, {% endif %}
|
||||||
{% endfor %}<br/>
|
{% endfor %}<br/>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -343,6 +343,11 @@ def generic_exam_urls(generic_exam_view: GenericExamViews):
|
|||||||
path("exam/", generic_exam_view.exam_list, name="exam_list"),
|
path("exam/", generic_exam_view.exam_list, name="exam_list"),
|
||||||
path("exam/all", generic_exam_view.exam_list_all, name="exam_list_all"),
|
path("exam/all", generic_exam_view.exam_list_all, name="exam_list_all"),
|
||||||
path("exam/<int:exam_id>/cids", generic_exam_view.exam_cids, name="exam_cids"),
|
path("exam/<int:exam_id>/cids", generic_exam_view.exam_cids, name="exam_cids"),
|
||||||
|
path(
|
||||||
|
"exam/<int:exam_id>/reset_answers",
|
||||||
|
generic_exam_view.exam_reset_answers,
|
||||||
|
name="exam_reset_answers",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"exam/<int:exam_id>/cids/edit",
|
"exam/<int:exam_id>/cids/edit",
|
||||||
generic_exam_view.exam_cids_edit,
|
generic_exam_view.exam_cids_edit,
|
||||||
|
|||||||
+25
-3
@@ -1042,6 +1042,29 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
|
|
||||||
return render(request, "exam_users_edit.html", context)
|
return render(request, "exam_users_edit.html", context)
|
||||||
|
|
||||||
|
def exam_reset_answers(self, request, exam_id):
|
||||||
|
if request.htmx:
|
||||||
|
exam = get_object_or_404(self.Exam, pk=exam_id)
|
||||||
|
|
||||||
|
if not request.user.groups.filter(name="cid_user_manager").exists():
|
||||||
|
# raise PermissionDenied
|
||||||
|
if request.user not in exam.author.all():
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
## Delete all answers
|
||||||
|
exam.cid_user_answers.all().delete()
|
||||||
|
|
||||||
|
# User statuses
|
||||||
|
exam.exam_user_status.all().delete()
|
||||||
|
|
||||||
|
# CidUserExams
|
||||||
|
exam.cid_users.all().delete()
|
||||||
|
|
||||||
|
return HttpResponse("<b>Answers reset</b>")
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Http404("Invalid request")
|
||||||
|
|
||||||
def exam_cids_edit(self, request, exam_id):
|
def exam_cids_edit(self, request, exam_id):
|
||||||
exam = get_object_or_404(self.Exam, pk=exam_id)
|
exam = get_object_or_404(self.Exam, pk=exam_id)
|
||||||
|
|
||||||
@@ -2166,9 +2189,8 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
# so we need to check for those
|
# so we need to check for those
|
||||||
if self.app_name == "longs":
|
if self.app_name == "longs":
|
||||||
for question in questions:
|
for question in questions:
|
||||||
#if question not in by_question:
|
# If either question or user do not exist we give a default
|
||||||
# continue
|
# not answered == score of 3
|
||||||
|
|
||||||
if user not in by_question[question]:
|
if user not in by_question[question]:
|
||||||
#print("NOT in")
|
#print("NOT in")
|
||||||
by_question[question][user] = ("Not answered", 3.0)
|
by_question[question][user] = ("Not answered", 3.0)
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
{% extends 'generic/exam_scores_base.html' %}
|
{% extends 'generic/exam_scores_base.html' %}
|
||||||
|
|
||||||
{% block table_answers %}
|
{% block table_answers %}
|
||||||
aoeu
|
|
||||||
eu
|
|
||||||
{% for question in questions %}
|
{% for question in questions %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{% url 'anatomy:mark' exam_pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter}}</a>
|
<td><a href="{% url 'anatomy:mark' exam_pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter}}</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user