diff --git a/anatomy/static/css/anatomy.css b/anatomy/static/css/anatomy.css index 331b18be..f7a96795 100644 --- a/anatomy/static/css/anatomy.css +++ b/anatomy/static/css/anatomy.css @@ -749,6 +749,7 @@ input { float: right; transform: rotate(90deg) translateX(10px); color: blueviolet; + user-select: none; } .clear-both { diff --git a/anatomy/templates/anatomy/base.html b/anatomy/templates/anatomy/base.html index 6de0ab9c..35770640 100644 --- a/anatomy/templates/anatomy/base.html +++ b/anatomy/templates/anatomy/base.html @@ -12,6 +12,9 @@ Anatomy: Create Exam / Questions / Create Question +{% if request.user.is_superuser %} + / Answers +{% endif %} {% endif %} {% endblock %} {% block content %} diff --git a/anatomy/urls.py b/anatomy/urls.py index 6b28d006..f73dbed7 100644 --- a/anatomy/urls.py +++ b/anatomy/urls.py @@ -39,7 +39,7 @@ urlpatterns = [ ), path( "exam//review", - views.question_review, + views.GenericViews.question_review, name="question_review", ), path("exam///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//delete", views.UserAnswerDelete.as_view(), name="user_answer_delete", ), + path( + "user_answers/delete", + views.GenericViews.user_answer_delete_multiple, + name="user_answer_delete_multiple", + ), ] diff --git a/anatomy/views.py b/anatomy/views.py index 3fc66faf..bde88591 100644 --- a/anatomy/views.py +++ b/anatomy/views.py @@ -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"}) \ No newline at end of file +GenericViews = GenericViewBase("anatomy", AnatomyQuestion, CidUserAnswer, Exam) diff --git a/generic/views.py b/generic/views.py index daac31d8..f93a9a54 100644 --- a/generic/views.py +++ b/generic/views.py @@ -651,4 +651,41 @@ class ExamViews(View, LoginRequiredMixin): return JsonResponse(question_json) - \ No newline at end of file + +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"}) \ No newline at end of file diff --git a/rapids/templates/rapids/exam_scores_user.html b/rapids/templates/rapids/exam_scores_user.html index 4b9e5782..bdaeac12 100644 --- a/rapids/templates/rapids/exam_scores_user.html +++ b/rapids/templates/rapids/exam_scores_user.html @@ -2,10 +2,13 @@ {% block content %}
- Question 1 -
+
HIDE/SHOW
+
+ Question 1 +
+
+
Answers:
-
Answers:

Exam: {{ exam.name }}

@@ -29,6 +32,10 @@ {% endblock %} {% block js %}