.
This commit is contained in:
@@ -749,6 +749,7 @@ input {
|
||||
float: right;
|
||||
transform: rotate(90deg) translateX(10px);
|
||||
color: blueviolet;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.clear-both {
|
||||
|
||||
@@ -12,6 +12,9 @@ Anatomy:
|
||||
<a href="{% url 'anatomy:exam_create' %}" title="Create a new exam">Create Exam</a> /
|
||||
<a href="{% url 'anatomy:anatomy_question_view' %}">Questions</a> /
|
||||
<a href="{% url 'anatomy:anatomy_question_create' %}" title="Create a new question">Create Question</a>
|
||||
{% if request.user.is_superuser %}
|
||||
/ <a href="{% url 'anatomy:user_answer_table_view' %}" title="User answers">Answers</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
+8
-3
@@ -39,7 +39,7 @@ urlpatterns = [
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/review",
|
||||
views.question_review,
|
||||
views.GenericViews.question_review,
|
||||
name="question_review",
|
||||
),
|
||||
path("exam/<int:pk>/<int:sk>/mark", views.mark, name="mark"),
|
||||
@@ -117,12 +117,17 @@ urlpatterns = [
|
||||
),
|
||||
path(
|
||||
"user_answers/",
|
||||
views.AnatomyUserAnswerView.as_view(),
|
||||
name="anatomy_user_answer_view",
|
||||
views.UserAnswerTableView.as_view(),
|
||||
name="user_answer_table_view",
|
||||
),
|
||||
path(
|
||||
"user_answers/<int:pk>/delete",
|
||||
views.UserAnswerDelete.as_view(),
|
||||
name="user_answer_delete",
|
||||
),
|
||||
path(
|
||||
"user_answers/delete",
|
||||
views.GenericViews.user_answer_delete_multiple,
|
||||
name="user_answer_delete_multiple",
|
||||
),
|
||||
]
|
||||
|
||||
+3
-20
@@ -46,7 +46,7 @@ from .models import (
|
||||
# IncorrectAnswers,
|
||||
)
|
||||
from generic.models import Examination
|
||||
from generic.views import ExamViews
|
||||
from generic.views import ExamViews, GenericViewBase
|
||||
from reversion.views import RevisionMixin
|
||||
|
||||
from .decorators import user_is_author_or_anatomy_checker
|
||||
@@ -959,7 +959,7 @@ class AnatomyQuestionView(LoginRequiredMixin, SingleTableMixin, FilterView):
|
||||
|
||||
filterset_class = AnatomyQuestionFilter
|
||||
|
||||
class AnatomyUserAnswerView(LoginRequiredMixin, SingleTableMixin, FilterView):
|
||||
class UserAnswerTableView(LoginRequiredMixin, SingleTableMixin, FilterView):
|
||||
model = CidUserAnswer
|
||||
table_class = AnatomyUserAnswerTable
|
||||
template_name = "anatomy/anatomy_question_view.html"
|
||||
@@ -1033,21 +1033,4 @@ class ExamDelete(RevisionMixin, AuthorOrCheckerRequiredMixin, DeleteView):
|
||||
template_name = "exam_confirm_delete.html"
|
||||
success_url = reverse_lazy("anatomy:index")
|
||||
|
||||
def question_review(request, pk):
|
||||
"""
|
||||
Return a json representation of the question when the exam is active
|
||||
"""
|
||||
if request.is_ajax():
|
||||
exam = get_object_or_404(Exam, pk=pk)
|
||||
|
||||
print(request.POST["question_number"])
|
||||
print(type(request.POST["question_number"]))
|
||||
|
||||
if not exam.publish_results:
|
||||
raise Http404
|
||||
|
||||
question = exam.exam_questions.all()[int(request.POST["question_number"])]
|
||||
|
||||
question_json = question.get_question_json(based=False)
|
||||
return JsonResponse(question_json)
|
||||
return JsonResponse({"status": "error"})
|
||||
GenericViews = GenericViewBase("anatomy", AnatomyQuestion, CidUserAnswer, Exam)
|
||||
|
||||
+38
-1
@@ -651,4 +651,41 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
|
||||
return JsonResponse(question_json)
|
||||
|
||||
|
||||
|
||||
class GenericViewBase:
|
||||
def __init__(self, app_name, QuestionObject, CidUserAnswerObject, ExamObject, question_type, loadJsonAnswer):
|
||||
self.question_object = QuestionObject
|
||||
self.cid_user_answer_object = CidUserAnswerObject
|
||||
self.exam_object = ExamObject
|
||||
self.app_name = app_name
|
||||
|
||||
def question_review(self, request, pk):
|
||||
"""
|
||||
Return a json representation of the question when the exam is active
|
||||
"""
|
||||
if request.is_ajax():
|
||||
exam = get_object_or_404(self.exam_object, pk=pk)
|
||||
|
||||
print(request.POST["question_number"])
|
||||
print(type(request.POST["question_number"]))
|
||||
|
||||
if not exam.publish_results:
|
||||
raise Http404
|
||||
|
||||
question = exam.exam_questions.all()[int(request.POST["question_number"])]
|
||||
|
||||
question_json = question.get_question_json(based=False)
|
||||
return JsonResponse(question_json)
|
||||
return JsonResponse({"status": "error"})
|
||||
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
def user_answer_delete_multiple(self, request):
|
||||
if request.is_ajax():
|
||||
print(request.POST["answer_ids"])
|
||||
answer_ids = json.loads(request.POST["answer_ids"])
|
||||
|
||||
# We could probably delete them all at once....
|
||||
for id in answer_ids:
|
||||
self.cid_user_answer_object.objects.get(pk=id).delete()
|
||||
return JsonResponse({"status": "success"})
|
||||
return JsonResponse({"status": "error"})
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="question-display-block">
|
||||
Question <span class="question-number">1</span>
|
||||
<div id="single-dicom-viewer" class="dicom-viewer" data-images="" data-annotations=''>
|
||||
<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="answers">Answers: </div>
|
||||
</div>
|
||||
<div class="answers">Answers: </div>
|
||||
</div>
|
||||
<div class="rapids">
|
||||
<h2>Exam: {{ exam.name }}</h2>
|
||||
@@ -29,6 +32,10 @@
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<script>
|
||||
$(".hide-show").click((evt, el) => {
|
||||
$(".inner-display-block").toggle();
|
||||
})
|
||||
|
||||
$(document).ready(function () {
|
||||
$(".view-question-link").on("click", function (e) {
|
||||
console.log("click", e)
|
||||
|
||||
Reference in New Issue
Block a user