unify generic exam views naming
This commit is contained in:
+18
-18
@@ -8,7 +8,7 @@ app_name = "anatomy"
|
||||
|
||||
urlpatterns = [
|
||||
# path('', views.question_list, name='question_list'),
|
||||
path("", views.AnatomyExamViews.index, name="index"),
|
||||
path("", views.GenericExamViews.index, name="index"),
|
||||
path(
|
||||
"question/",
|
||||
views.AnatomyQuestionView.as_view(),
|
||||
@@ -62,29 +62,29 @@ urlpatterns = [
|
||||
"exam/<int:exam_pk>/<int:sk>/mark/review", views.mark_review, name="mark_review"
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/mark", views.AnatomyExamViews.mark_overview, name="mark_overview"
|
||||
"exam/<int:pk>/mark", views.GenericExamViews.mark_overview, name="mark_overview"
|
||||
),
|
||||
# path("exam/<int:pk>/<int:sk>/", views.exam_take, name="exam_take"),
|
||||
path(
|
||||
"exam/<int:pk>/question/<int:sk>/",
|
||||
views.AnatomyExamViews.exam_question_detail,
|
||||
views.GenericExamViews.exam_question_detail,
|
||||
name="exam_question_detail",
|
||||
),
|
||||
path("exam/<int:pk>/", views.AnatomyExamViews.exam_overview, name="exam_overview"),
|
||||
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
|
||||
path(
|
||||
"exam/<int:pk>/json_edit",
|
||||
views.AnatomyExamViews.exam_json_edit,
|
||||
views.GenericExamViews.exam_json_edit,
|
||||
name="exam_json_edit",
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/scores",
|
||||
views.AnatomyExamViews.exam_scores_cid,
|
||||
views.GenericExamViews.exam_scores_cid,
|
||||
# cache_page(60 * 1)(views.exam_scores_cid),
|
||||
name="exam_scores_cid",
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/scores/refresh",
|
||||
views.AnatomyExamViews.exam_scores_refresh,
|
||||
views.GenericExamViews.exam_scores_refresh,
|
||||
# cache_page(60 * 1)(views.exam_scores_cid),
|
||||
name="exam_scores_refresh",
|
||||
),
|
||||
@@ -95,41 +95,41 @@ urlpatterns = [
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/toggle_active",
|
||||
views.AnatomyExamViews.exam_toggle_active,
|
||||
views.GenericExamViews.exam_toggle_active,
|
||||
name="exam_toggle_active",
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/toggle_results_published",
|
||||
views.AnatomyExamViews.exam_toggle_results_published,
|
||||
views.GenericExamViews.exam_toggle_results_published,
|
||||
name="exam_toggle_results_published",
|
||||
),
|
||||
path(
|
||||
"exam/submit",
|
||||
views.AnatomyExamViews.postExamAnswers,
|
||||
views.GenericExamViews.postExamAnswers,
|
||||
name="exam_answers_submit",
|
||||
),
|
||||
path("exam/", views.AnatomyExamViews.exam_list, name="exam_list"),
|
||||
path("exam/all", views.AnatomyExamViews.exam_list_all, name="exam_list_all"),
|
||||
path("exam/", views.GenericExamViews.exam_list, name="exam_list"),
|
||||
path("exam/all", views.GenericExamViews.exam_list_all, name="exam_list_all"),
|
||||
path("exam/create", views.ExamCreate.as_view(), name="exam_create"),
|
||||
path("exam/<int:exam_id>/clone", views.ExamClone.as_view(), name="exam_clone"),
|
||||
path("exam/<int:exam_id>/cids", views.AnatomyExamViews.exam_cids, name="exam_cids"),
|
||||
path("exam/<int:exam_id>/cids", views.GenericExamViews.exam_cids, name="exam_cids"),
|
||||
path("exam/<int:pk>/update", views.ExamUpdate.as_view(), name="exam_update"),
|
||||
path("exam/<int:pk>/delete", views.ExamDelete.as_view(), name="exam_delete"),
|
||||
path("exam/json/", views.AnatomyExamViews.active_exams, name="active_exams"),
|
||||
path("exam/json/<int:pk>", views.AnatomyExamViews.exam_json, name="exam_json"),
|
||||
path("exam/json/", views.GenericExamViews.active_exams, name="active_exams"),
|
||||
path("exam/json/<int:pk>", views.GenericExamViews.exam_json, name="exam_json"),
|
||||
path(
|
||||
"exam/json/<int:pk>/unbased",
|
||||
views.AnatomyExamViews.exam_json_unbased,
|
||||
views.GenericExamViews.exam_json_unbased,
|
||||
name="exam_json_unbased",
|
||||
),
|
||||
path(
|
||||
"exam/json/<int:pk>/<int:sk>/unbased",
|
||||
views.AnatomyExamViews.exam_question_json_unbased,
|
||||
views.GenericExamViews.exam_question_json_unbased,
|
||||
name="exam_question_json_unbased",
|
||||
),
|
||||
path(
|
||||
"exam/json/<int:pk>/recreate",
|
||||
views.AnatomyExamViews.exam_json_recreate,
|
||||
views.GenericExamViews.exam_json_recreate,
|
||||
name="exam_json_recreate",
|
||||
),
|
||||
# path("cid/", views.cid_selector, name="cid_selector"),
|
||||
|
||||
+12
-10
@@ -136,8 +136,8 @@ def answer_question(request, pk):
|
||||
)
|
||||
|
||||
|
||||
#@login_required
|
||||
#def exam_take(request, pk, sk):
|
||||
# @login_required
|
||||
# def exam_take(request, pk, sk):
|
||||
# """
|
||||
# Allows taking of the exam on the django server (when logged in)
|
||||
#
|
||||
@@ -212,7 +212,7 @@ def answer_question(request, pk):
|
||||
# )
|
||||
|
||||
|
||||
#def flag_question(request):
|
||||
# def flag_question(request):
|
||||
# pk = request.GET.get("pk", None)
|
||||
# ans = UserAnswer.objects.filter(user=request.user, question__pk=pk).first()
|
||||
# ans.flagged = not ans.flagged
|
||||
@@ -244,7 +244,9 @@ def loadJsonAnswer(answer):
|
||||
exam = get_object_or_404(Exam, pk=eid)
|
||||
|
||||
if not exam.check_cid_user(answer["cid"], answer["passcode"]):
|
||||
return False, JsonResponse({"success": False, "error": "invalid cid / passcode"})
|
||||
return False, JsonResponse(
|
||||
{"success": False, "error": "invalid cid / passcode"}
|
||||
)
|
||||
|
||||
# if not exam.active:
|
||||
# return False, JsonResponse(
|
||||
@@ -452,6 +454,7 @@ def mark(request, exam_pk, sk, unmarked_exam_answers_only=True, review=False):
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
def exam_scores_refresh(request, pk):
|
||||
exam = get_object_or_404(Exam, pk=pk)
|
||||
@@ -461,9 +464,7 @@ def exam_scores_refresh(request, pk):
|
||||
|
||||
questions = exam.exam_questions.all()
|
||||
|
||||
cids = (
|
||||
CidUserAnswer.objects.filter(question__in=questions, exam__id=pk)
|
||||
)
|
||||
cids = CidUserAnswer.objects.filter(question__in=questions, exam__id=pk)
|
||||
|
||||
# Force a score update
|
||||
for c in cids:
|
||||
@@ -477,8 +478,9 @@ def exam_scores_refresh(request, pk):
|
||||
},
|
||||
)
|
||||
|
||||
#@login_required
|
||||
#def exam_scores_cid(request, pk):
|
||||
|
||||
# @login_required
|
||||
# def exam_scores_cid(request, pk):
|
||||
# exam = get_object_or_404(Exam, pk=pk)
|
||||
#
|
||||
# if not exam.exam_mode:
|
||||
@@ -1001,7 +1003,7 @@ def question_save_annotation(request, pk):
|
||||
return JsonResponse(data, status=400)
|
||||
|
||||
|
||||
AnatomyExamViews = ExamViews(
|
||||
GenericExamViews = ExamViews(
|
||||
Exam, AnatomyQuestion, CidUserAnswer, "anatomy", "anatomy", loadJsonAnswer
|
||||
)
|
||||
|
||||
|
||||
@@ -856,6 +856,7 @@ class ExamViews(View, LoginRequiredMixin):
|
||||
cache.set("{}_question_json_{}".format(self.app_name, sk), question_json, 3600)
|
||||
|
||||
return JsonResponse(question_json)
|
||||
|
||||
def exam_scores_cid(self, request, pk):
|
||||
exam = get_object_or_404(self.Exam, pk=pk)
|
||||
|
||||
|
||||
+20
-16
@@ -5,7 +5,7 @@ app_name = "longs"
|
||||
|
||||
urlpatterns = [
|
||||
# path('', views.question_list, name='question_list'),
|
||||
path("", views.LongExamViews.index, name="index"),
|
||||
path("", views.GenericExamViews.index, name="index"),
|
||||
path("author/<int:pk>/", views.author_detail, name="author_detail"),
|
||||
path("author/", views.author_list, name="author_list"),
|
||||
path("question/", views.LongView.as_view(), name="long_view"),
|
||||
@@ -81,17 +81,19 @@ urlpatterns = [
|
||||
views.mark_question_overview,
|
||||
name="mark_question_overview",
|
||||
),
|
||||
path("exam/<int:pk>/mark", views.LongExamViews.mark_overview, name="mark_overview"),
|
||||
path(
|
||||
"exam/<int:pk>/mark", views.GenericExamViews.mark_overview, name="mark_overview"
|
||||
),
|
||||
# path("exam/<int:pk>/<int:sk>/", views.exam_take, name="exam_take"),
|
||||
path(
|
||||
"exam/<int:pk>/question/<int:sk>/",
|
||||
views.LongExamViews.exam_question_detail,
|
||||
views.GenericExamViews.exam_question_detail,
|
||||
name="exam_question_detail",
|
||||
),
|
||||
path("exam/<int:pk>/", views.LongExamViews.exam_overview, name="exam_overview"),
|
||||
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
|
||||
path(
|
||||
"exam/<int:pk>/json_edit",
|
||||
views.LongExamViews.exam_json_edit,
|
||||
views.GenericExamViews.exam_json_edit,
|
||||
name="exam_json_edit",
|
||||
),
|
||||
path(
|
||||
@@ -107,43 +109,45 @@ urlpatterns = [
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/toggle_active",
|
||||
views.LongExamViews.exam_toggle_active,
|
||||
views.GenericExamViews.exam_toggle_active,
|
||||
name="exam_toggle_active",
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/toggle_results_published",
|
||||
views.LongExamViews.exam_toggle_results_published,
|
||||
views.GenericExamViews.exam_toggle_results_published,
|
||||
name="exam_toggle_results_published",
|
||||
),
|
||||
path(
|
||||
"exam/submit", views.LongExamViews.postExamAnswers, name="exam_answers_submit"
|
||||
"exam/submit",
|
||||
views.GenericExamViews.postExamAnswers,
|
||||
name="exam_answers_submit",
|
||||
),
|
||||
path("exam/", views.LongExamViews.exam_list, name="exam_list"),
|
||||
path("exam/all", views.LongExamViews.exam_list_all, name="exam_list_all"),
|
||||
path("exam/", views.GenericExamViews.exam_list, name="exam_list"),
|
||||
path("exam/all", views.GenericExamViews.exam_list_all, name="exam_list_all"),
|
||||
path("exam/create", views.ExamCreate.as_view(), name="exam_create"),
|
||||
path("exam/<int:exam_id>/clone", views.ExamClone.as_view(), name="exam_clone"),
|
||||
path("exam/<int:pk>/update", views.ExamUpdate.as_view(), name="exam_update"),
|
||||
path("exam/<int:pk>/delete", views.ExamDelete.as_view(), name="exam_delete"),
|
||||
path("exam/json/", views.LongExamViews.active_exams, name="active_exams"),
|
||||
path("exam/json/<int:pk>", views.LongExamViews.exam_json, name="exam_json"),
|
||||
path("exam/json/", views.GenericExamViews.active_exams, name="active_exams"),
|
||||
path("exam/json/<int:pk>", views.GenericExamViews.exam_json, name="exam_json"),
|
||||
path(
|
||||
"exam/json/<int:pk>/unbased",
|
||||
views.LongExamViews.exam_json_unbased,
|
||||
views.GenericExamViews.exam_json_unbased,
|
||||
name="exam_json_unbased",
|
||||
),
|
||||
path(
|
||||
"exam/json/<int:pk>/<int:sk>",
|
||||
views.LongExamViews.exam_question_json,
|
||||
views.GenericExamViews.exam_question_json,
|
||||
name="exam_question_json",
|
||||
),
|
||||
path(
|
||||
"exam/json/<int:pk>/unbased/<int:sk>",
|
||||
views.LongExamViews.exam_question_json_unbased,
|
||||
views.GenericExamViews.exam_question_json_unbased,
|
||||
name="exam_question_json_unbased",
|
||||
),
|
||||
path(
|
||||
"exam/json/<int:pk>/recreate",
|
||||
views.LongExamViews.exam_json_recreate,
|
||||
views.GenericExamViews.exam_json_recreate,
|
||||
name="exam_json_recreate",
|
||||
),
|
||||
path("create/", views.LongCreate.as_view(), name="long_create"),
|
||||
|
||||
+5
-4
@@ -315,7 +315,6 @@ class LongSeriesCreate(RevisionMixin, LoginRequiredMixin, CreateView):
|
||||
kwargs.update({"user": self.request.user})
|
||||
return kwargs
|
||||
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(LongSeriesCreate, self).get_context_data(**kwargs)
|
||||
|
||||
@@ -635,7 +634,9 @@ def loadJsonAnswer(answer):
|
||||
exam = get_object_or_404(Exam, pk=eid)
|
||||
|
||||
if not exam.check_cid_user(answer["cid"], answer["passcode"]):
|
||||
return False, JsonResponse({"success": False, "error": "invalid cid / passcode"})
|
||||
return False, JsonResponse(
|
||||
{"success": False, "error": "invalid cid / passcode"}
|
||||
)
|
||||
|
||||
# if not exam.active:
|
||||
# return False, JsonResponse(
|
||||
@@ -1107,7 +1108,7 @@ def exam_scores_cid_user(request, pk, sk, passcode):
|
||||
{
|
||||
"exam": exam,
|
||||
"cid": cid,
|
||||
"passcode" : passcode,
|
||||
"passcode": passcode,
|
||||
"questions": questions,
|
||||
# "answers": answers,
|
||||
"answers_marks": answers_marks,
|
||||
@@ -1169,7 +1170,7 @@ def long_series_order_upload_filename(request, pk):
|
||||
return redirect("longs:long_series_detail", pk=pk)
|
||||
|
||||
|
||||
LongExamViews = ExamViews(Exam, Long, CidUserAnswer, "longs", "long", loadJsonAnswer)
|
||||
GenericExamViews = ExamViews(Exam, Long, CidUserAnswer, "longs", "long", loadJsonAnswer)
|
||||
|
||||
|
||||
class ExamCreate(RevisionMixin, LoginRequiredMixin, CreateView):
|
||||
|
||||
+46
-20
@@ -5,34 +5,60 @@ app_name = "physics"
|
||||
|
||||
urlpatterns = [
|
||||
# path('', views.question_list, name='question_list'),
|
||||
path("", views.PhysicsExamViews.index, name="index"),
|
||||
#path("question/", views.QuestionView.as_view(), name="question_view"),
|
||||
path("", views.GenericExamViews.index, name="index"),
|
||||
# path("question/", views.QuestionView.as_view(), name="question_view"),
|
||||
path("question/", views.QuestionView.as_view(), name="question_view"),
|
||||
path("question/<int:pk>/", views.question_detail, name="question_detail"),
|
||||
#path("question/create/", views.QuestionCreate.as_view(), name="anatomy_question_create"),
|
||||
#path("question/<int:pk>/update", views.QuestionUpdate.as_view(), name="anatomy_question_update"),
|
||||
#path("exam/<int:pk>/<int:sk>/mark", views.mark, name="mark"),
|
||||
#path("exam/<int:pk>/mark", views.mark_overview, name="mark_overview"),
|
||||
# path("question/create/", views.QuestionCreate.as_view(), name="anatomy_question_create"),
|
||||
# path("question/<int:pk>/update", views.QuestionUpdate.as_view(), name="anatomy_question_update"),
|
||||
# path("exam/<int:pk>/<int:sk>/mark", views.mark, name="mark"),
|
||||
# path("exam/<int:pk>/mark", views.mark_overview, name="mark_overview"),
|
||||
path("exam/<int:pk>/take_old", views.exam_take_old, name="exam_take_old"),
|
||||
path("exam/<int:pk>/<int:sk>/<str:cid>/<str:passcode>/take", views.exam_take, name="exam_take"),
|
||||
path(
|
||||
"exam/<int:pk>/<int:sk>/<str:cid>/<str:passcode>/take",
|
||||
views.exam_take,
|
||||
name="exam_take",
|
||||
),
|
||||
path("exam/<int:pk>/start", views.exam_start, name="exam_start"),
|
||||
path("exam/<int:pk>/<str:cid>/<str:passcode>/finish", views.exam_finish, name="exam_finish"),
|
||||
path("exam/<int:pk>/", views.PhysicsExamViews.exam_overview, name="exam_overview"),
|
||||
path("exam/<int:pk>/scores", views.exam_scores_cid,
|
||||
name="exam_scores_cid"),
|
||||
path("exam/<int:pk>/scores/<int:cid>/<str:passcode>/", views.exam_scores_cid_user,
|
||||
name="exam_scores_cid_user"),
|
||||
path("exam/<int:pk>/toggle_active", views.PhysicsExamViews.exam_toggle_active, name="exam_toggle_active"),
|
||||
path("exam/<int:pk>/toggle_results_published", views.PhysicsExamViews.exam_toggle_results_published, name="exam_toggle_results_published"),
|
||||
path(
|
||||
"exam/<int:pk>/<str:cid>/<str:passcode>/finish",
|
||||
views.exam_finish,
|
||||
name="exam_finish",
|
||||
),
|
||||
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
|
||||
path("exam/<int:pk>/scores", views.exam_scores_cid, name="exam_scores_cid"),
|
||||
path(
|
||||
"exam/<int:pk>/scores/<int:cid>/<str:passcode>/",
|
||||
views.exam_scores_cid_user,
|
||||
name="exam_scores_cid_user",
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/toggle_active",
|
||||
views.GenericExamViews.exam_toggle_active,
|
||||
name="exam_toggle_active",
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/toggle_results_published",
|
||||
views.GenericExamViews.exam_toggle_results_published,
|
||||
name="exam_toggle_results_published",
|
||||
),
|
||||
path("exam/<int:exam_id>/clone", views.ExamClone.as_view(), name="exam_clone"),
|
||||
path("exam/<int:pk>/update", views.ExamUpdate.as_view(), name="exam_update"),
|
||||
path("exam/<int:pk>/delete", views.ExamDelete.as_view(), name="exam_delete"),
|
||||
path("exam/submit", views.PhysicsExamViews.postExamAnswers, name="exam_answers_submit"),
|
||||
path("exam/", views.PhysicsExamViews.exam_list, name="exam_list"),
|
||||
path(
|
||||
"exam/submit",
|
||||
views.GenericExamViews.postExamAnswers,
|
||||
name="exam_answers_submit",
|
||||
),
|
||||
path("exam/", views.GenericExamViews.exam_list, name="exam_list"),
|
||||
path("exam/available", views.active_exams, name="active_exams"),
|
||||
#path("exam/json/<int:pk>", views.exam_json, name="exam_json"),
|
||||
#path("exam/json/<int:pk>/recreate", views.exam_json_recreate, name="exam_json_recreate"),
|
||||
path("user_answers/", views.UserAnswerTableView.as_view(), name="user_answer_table_view"),
|
||||
# path("exam/json/<int:pk>", views.exam_json, name="exam_json"),
|
||||
# path("exam/json/<int:pk>/recreate", views.exam_json_recreate, name="exam_json_recreate"),
|
||||
path(
|
||||
"user_answers/",
|
||||
views.UserAnswerTableView.as_view(),
|
||||
name="user_answer_table_view",
|
||||
),
|
||||
path(
|
||||
"user_answers/<int:pk>", views.UserAnswerView.as_view(), name="user_answer_view"
|
||||
),
|
||||
|
||||
+1
-1
@@ -463,7 +463,7 @@ def loadJsonAnswer(answer):
|
||||
return True, None
|
||||
|
||||
|
||||
PhysicsExamViews = ExamViews(
|
||||
GenericExamViews = ExamViews(
|
||||
Exam, Question, CidUserAnswer, "physics", "physics", loadJsonAnswer
|
||||
)
|
||||
|
||||
|
||||
+26
-23
@@ -47,9 +47,9 @@ from sbas.models import CidUserAnswer as SbasCidUserAnswer
|
||||
from sbas.models import Exam as SbasExam
|
||||
from sbas.models import Question as SbasQuestion
|
||||
|
||||
from anatomy.views import AnatomyExamViews
|
||||
from rapids.views import RapidExamViews
|
||||
from longs.views import LongExamViews
|
||||
from anatomy.views import GenericExamViews
|
||||
from rapids.views import GenericExamViews
|
||||
from longs.views import GenericExamViews
|
||||
|
||||
from generic.forms import QuestionNoteForm
|
||||
from generic.models import CidUser, QuestionNote
|
||||
@@ -75,6 +75,7 @@ def cid_selector(request):
|
||||
"cid_selector.html",
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
@user_passes_test(lambda u: u.is_superuser)
|
||||
def cid_scores_admin(request, cid):
|
||||
@@ -82,6 +83,7 @@ def cid_scores_admin(request, cid):
|
||||
|
||||
return cid_scores(request, cid_user.cid, cid_user.passcode)
|
||||
|
||||
|
||||
def cid_scores(request, pk, passcode):
|
||||
# exam = get_object_or_404(Exam, pk=pk)
|
||||
|
||||
@@ -95,11 +97,11 @@ def cid_scores(request, pk, passcode):
|
||||
|
||||
# questions = exam.exam_questions.all()
|
||||
EXAM_ANSWER_MAP = {
|
||||
"physics" : (PhysicsCidUserAnswer, PhysicsExam),
|
||||
"anatomy" : (AnatomyCidUserAnswer, AnatomyExam),
|
||||
"rapids" : (RapidsCidUserAnswer, RapidsExam),
|
||||
"longs" : (LongsCidUserAnswer, LongsExam),
|
||||
"sbas" : (SbasCidUserAnswer, SbasExam),
|
||||
"physics": (PhysicsCidUserAnswer, PhysicsExam),
|
||||
"anatomy": (AnatomyCidUserAnswer, AnatomyExam),
|
||||
"rapids": (RapidsCidUserAnswer, RapidsExam),
|
||||
"longs": (LongsCidUserAnswer, LongsExam),
|
||||
"sbas": (SbasCidUserAnswer, SbasExam),
|
||||
}
|
||||
kwargs = {"exam_mode": True}
|
||||
|
||||
@@ -110,18 +112,17 @@ def cid_scores(request, pk, passcode):
|
||||
exam_ids = exam_answers.values_list("exam").distinct()
|
||||
exams.append((exam_type, Exam.objects.filter(id__in=exam_ids, **kwargs)))
|
||||
|
||||
|
||||
available_exams = cid_user.get_cid_exams()
|
||||
|
||||
return render(
|
||||
request,
|
||||
"cid_scores.html",
|
||||
{
|
||||
#"physics_exams": physics_exams,
|
||||
#"anatomy_exams": anatomy_exams,
|
||||
#"rapid_exams": rapid_exams,
|
||||
#"longs_exams": longs_exams,
|
||||
#"sba_exams": sba_exams,
|
||||
# "physics_exams": physics_exams,
|
||||
# "anatomy_exams": anatomy_exams,
|
||||
# "rapid_exams": rapid_exams,
|
||||
# "longs_exams": longs_exams,
|
||||
# "sba_exams": sba_exams,
|
||||
"all_exams": exams,
|
||||
"cid": cid,
|
||||
"passcode": passcode,
|
||||
@@ -140,13 +141,15 @@ def active_exams(request, cid=None, passcode=None):
|
||||
if not cid_user or cid_user.passcode != passcode:
|
||||
return JsonResponse({"status": "invalid"}, status=401)
|
||||
|
||||
anatomy_exams = AnatomyExamViews.active_exams(
|
||||
anatomy_exams = GenericExamViews.active_exams(
|
||||
request, False, cid=cid, passcode=passcode
|
||||
)
|
||||
rapid_exams = RapidExamViews.active_exams(
|
||||
rapid_exams = GenericExamViews.active_exams(
|
||||
request, False, cid=cid, passcode=passcode
|
||||
)
|
||||
long_exams = GenericExamViews.active_exams(
|
||||
request, False, cid=cid, passcode=passcode
|
||||
)
|
||||
long_exams = LongExamViews.active_exams(request, False, cid=cid, passcode=passcode)
|
||||
|
||||
exams = []
|
||||
exams.extend(anatomy_exams)
|
||||
@@ -164,9 +167,9 @@ def active_exams(request, cid=None, passcode=None):
|
||||
|
||||
|
||||
def active_exams_unbased(request):
|
||||
anatomy_exams = AnatomyExamViews.active_exams(request, False, False)
|
||||
rapid_exams = RapidExamViews.active_exams(request, False, False)
|
||||
long_exams = LongExamViews.active_exams(request, False, False)
|
||||
anatomy_exams = GenericExamViews.active_exams(request, False, False)
|
||||
rapid_exams = GenericExamViews.active_exams(request, False, False)
|
||||
long_exams = GenericExamViews.active_exams(request, False, False)
|
||||
|
||||
exams = []
|
||||
exams.extend(anatomy_exams)
|
||||
@@ -189,11 +192,11 @@ def exam_submit(request):
|
||||
exam_type, exam_id = request.POST.get("eid").split("/")
|
||||
|
||||
if exam_type == "anatomy":
|
||||
return AnatomyExamViews.postExamAnswers(request)
|
||||
return GenericExamViews.postExamAnswers(request)
|
||||
elif exam_type == "rapid":
|
||||
return RapidExamViews.postExamAnswers(request)
|
||||
return GenericExamViews.postExamAnswers(request)
|
||||
elif exam_type == "long":
|
||||
return LongExamViews.postExamAnswers(request)
|
||||
return GenericExamViews.postExamAnswers(request)
|
||||
return JsonResponse({"success": False, "error": "Invalid exam type"})
|
||||
|
||||
# postExamAnswers
|
||||
|
||||
+19
-17
@@ -8,7 +8,7 @@ app_name = "rapids"
|
||||
|
||||
urlpatterns = [
|
||||
# path('', views.question_list, name='question_list'),
|
||||
path("", views.RapidExamViews.index, name="index"),
|
||||
path("", views.GenericExamViews.index, name="index"),
|
||||
path("author/<int:pk>/", views.GenericViews.author_detail, name="author_detail"),
|
||||
path("author/", views.GenericViews.author_list, name="author_list"),
|
||||
path("question_viewer", views.question_viewer, name="question_viewer"),
|
||||
@@ -56,28 +56,28 @@ urlpatterns = [
|
||||
"exam/<int:exam_pk>/<int:sk>/mark/review", views.mark_review, name="mark_review"
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/mark", views.RapidExamViews.mark_overview, name="mark_overview"
|
||||
"exam/<int:pk>/mark", views.GenericExamViews.mark_overview, name="mark_overview"
|
||||
),
|
||||
# path("exam/<int:pk>/<int:sk>/", views.exam_take, name="exam_take"),
|
||||
path(
|
||||
"exam/<int:pk>/question/<int:sk>/",
|
||||
views.RapidExamViews.exam_question_detail,
|
||||
views.GenericExamViews.exam_question_detail,
|
||||
name="exam_question_detail",
|
||||
),
|
||||
path("exam/<int:pk>/", views.RapidExamViews.exam_overview, name="exam_overview"),
|
||||
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
|
||||
path(
|
||||
"exam/<int:pk>/json_edit",
|
||||
views.RapidExamViews.exam_json_edit,
|
||||
views.GenericExamViews.exam_json_edit,
|
||||
name="exam_json_edit",
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/scores",
|
||||
views.RapidExamViews.exam_scores_cid,
|
||||
views.GenericExamViews.exam_scores_cid,
|
||||
name="exam_scores_cid",
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/scores/refresh",
|
||||
views.RapidExamViews.exam_scores_refresh,
|
||||
views.GenericExamViews.exam_scores_refresh,
|
||||
# cache_page(60 * 1)(views.exam_scores_cid),
|
||||
name="exam_scores_refresh",
|
||||
),
|
||||
@@ -88,38 +88,40 @@ urlpatterns = [
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/toggle_active",
|
||||
views.RapidExamViews.exam_toggle_active,
|
||||
views.GenericExamViews.exam_toggle_active,
|
||||
name="exam_toggle_active",
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/toggle_results_published",
|
||||
views.RapidExamViews.exam_toggle_results_published,
|
||||
views.GenericExamViews.exam_toggle_results_published,
|
||||
name="exam_toggle_results_published",
|
||||
),
|
||||
path(
|
||||
"exam/submit", views.RapidExamViews.postExamAnswers, name="exam_answers_submit"
|
||||
"exam/submit",
|
||||
views.GenericExamViews.postExamAnswers,
|
||||
name="exam_answers_submit",
|
||||
),
|
||||
path("exam/", views.RapidExamViews.exam_list, name="exam_list"),
|
||||
path("exam/all", views.RapidExamViews.exam_list_all, name="exam_list_all"),
|
||||
path("exam/", views.GenericExamViews.exam_list, name="exam_list"),
|
||||
path("exam/all", views.GenericExamViews.exam_list_all, name="exam_list_all"),
|
||||
path("exam/create", views.ExamCreate.as_view(), name="exam_create"),
|
||||
path("exam/<int:exam_id>/clone", views.ExamClone.as_view(), name="exam_clone"),
|
||||
path("exam/<int:pk>/update", views.ExamUpdate.as_view(), name="exam_update"),
|
||||
path("exam/<int:pk>/delete", views.ExamDelete.as_view(), name="exam_delete"),
|
||||
path("exam/json/", views.RapidExamViews.active_exams, name="active_exams"),
|
||||
path("exam/json/<int:pk>", views.RapidExamViews.exam_json, name="exam_json"),
|
||||
path("exam/json/", views.GenericExamViews.active_exams, name="active_exams"),
|
||||
path("exam/json/<int:pk>", views.GenericExamViews.exam_json, name="exam_json"),
|
||||
path(
|
||||
"exam/json/<int:pk>/unbased",
|
||||
views.RapidExamViews.exam_json_unbased,
|
||||
views.GenericExamViews.exam_json_unbased,
|
||||
name="exam_json_unbased",
|
||||
),
|
||||
path(
|
||||
"exam/json/<int:pk>/<int:sk>/unbased",
|
||||
views.RapidExamViews.exam_question_json_unbased,
|
||||
views.GenericExamViews.exam_question_json_unbased,
|
||||
name="exam_question_json_unbased",
|
||||
),
|
||||
path(
|
||||
"exam/json/<int:pk>/recreate",
|
||||
views.RapidExamViews.exam_json_recreate,
|
||||
views.GenericExamViews.exam_json_recreate,
|
||||
name="exam_json_recreate",
|
||||
),
|
||||
path("create/", views.RapidCreate.as_view(), name="rapid_create"),
|
||||
|
||||
+1
-1
@@ -1047,7 +1047,7 @@ class QuestionDelete(AuthorOrCheckerRequiredMixin, DeleteView):
|
||||
success_url = reverse_lazy("rapids:rapid_view")
|
||||
|
||||
|
||||
RapidExamViews = ExamViews(
|
||||
GenericExamViews = ExamViews(
|
||||
Exam, Rapid, CidUserAnswer, "rapids", "rapid", loadJsonAnswer
|
||||
)
|
||||
|
||||
|
||||
+16
-8
@@ -7,17 +7,25 @@ app_name = "sbas"
|
||||
|
||||
urlpatterns = [
|
||||
# path('', views.question_list, name='question_list'),
|
||||
path("", views.SbasExamViews.index, name="index"),
|
||||
path("", views.GenericExamViews.index, name="index"),
|
||||
path("question/", views.QuestionView.as_view(), name="question_view"),
|
||||
path("question/<int:pk>/", views.question_detail, name="question_detail"),
|
||||
# path("question/create/", views.QuestionCreate.as_view(), name="anatomy_question_create"),
|
||||
# path("question/<int:pk>/update", views.QuestionUpdate.as_view(), name="anatomy_question_update"),
|
||||
# path("exam/<int:pk>/<int:sk>/mark", views.mark, name="mark"),
|
||||
# path("exam/<int:pk>/mark", views.mark_overview, name="mark_overview"),
|
||||
path("exam/<int:pk>/<int:sk>/<str:cid>/<str:passcode>/take", views.exam_take, name="exam_take"),
|
||||
path(
|
||||
"exam/<int:pk>/<int:sk>/<str:cid>/<str:passcode>/take",
|
||||
views.exam_take,
|
||||
name="exam_take",
|
||||
),
|
||||
path("exam/<int:pk>/start", views.exam_start, name="exam_start"),
|
||||
path("exam/<int:pk>/<str:cid>/<str:passcode>/finish", views.exam_finish, name="exam_finish"),
|
||||
path("exam/<int:pk>/", views.SbasExamViews.exam_overview, name="exam_overview"),
|
||||
path(
|
||||
"exam/<int:pk>/<str:cid>/<str:passcode>/finish",
|
||||
views.exam_finish,
|
||||
name="exam_finish",
|
||||
),
|
||||
path("exam/<int:pk>/", views.GenericExamViews.exam_overview, name="exam_overview"),
|
||||
path(
|
||||
"exam/<int:pk>/scores",
|
||||
cache_page(60 * 1)(views.exam_scores_cid),
|
||||
@@ -30,16 +38,16 @@ urlpatterns = [
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/toggle_active",
|
||||
views.SbasExamViews.exam_toggle_active,
|
||||
views.GenericExamViews.exam_toggle_active,
|
||||
name="exam_toggle_active",
|
||||
),
|
||||
path(
|
||||
"exam/<int:pk>/toggle_results_published",
|
||||
views.SbasExamViews.exam_toggle_results_published,
|
||||
views.GenericExamViews.exam_toggle_results_published,
|
||||
name="exam_toggle_results_published",
|
||||
),
|
||||
# path("exam/submit", views.PhysicsExamViews.postExamAnswers, name="exam_answers_submit"),
|
||||
path("exam/", views.SbasExamViews.exam_list, name="exam_list"),
|
||||
# path("exam/submit", views.GenericExamViews.postExamAnswers, name="exam_answers_submit"),
|
||||
path("exam/", views.GenericExamViews.exam_list, name="exam_list"),
|
||||
path("exam/available", views.active_exams, name="active_exams"),
|
||||
# path("exam/json/<int:pk>", views.exam_json, name="exam_json"),
|
||||
# path("exam/json/<int:pk>/recreate", views.exam_json_recreate, name="exam_json_recreate"),
|
||||
|
||||
+29
-15
@@ -47,6 +47,7 @@ from django.core.exceptions import PermissionDenied
|
||||
from .tables import QuestionTable, UserAnswerTable
|
||||
from .filters import QuestionFilter, UserAnswerFilter
|
||||
|
||||
|
||||
class AuthorOrCheckerRequiredMixin(object):
|
||||
def get_object(self, *args, **kwargs):
|
||||
obj = super().get_object(*args, **kwargs)
|
||||
@@ -56,6 +57,7 @@ class AuthorOrCheckerRequiredMixin(object):
|
||||
raise PermissionDenied() # or Http404
|
||||
return obj
|
||||
|
||||
|
||||
def question_list(request):
|
||||
questions = Question.objects.all()
|
||||
return render(request, "sbas/question_list.html", {"questions": questions})
|
||||
@@ -109,9 +111,17 @@ def exam_scores_cid(request, pk):
|
||||
s = q.cid_user_answers.filter(cid=cid, exam__id=pk).first()
|
||||
if not s:
|
||||
# skip if no answer
|
||||
user_answers_marks[cid].append((0,0,0,0,0))
|
||||
user_answers_marks[cid].append((0, 0, 0, 0, 0))
|
||||
user_answers[cid].append(("", "", "", "", ""))
|
||||
by_question[q].append((("", 0),("", 0),("", 0),("", 0),("", 0),))
|
||||
by_question[q].append(
|
||||
(
|
||||
("", 0),
|
||||
("", 0),
|
||||
("", 0),
|
||||
("", 0),
|
||||
("", 0),
|
||||
)
|
||||
)
|
||||
continue
|
||||
|
||||
ans = s.get_answer()
|
||||
@@ -191,7 +201,6 @@ def exam_scores_cid_user(request, pk, sk, passcode):
|
||||
answers_marks = []
|
||||
answers = []
|
||||
|
||||
|
||||
view_all_results = False
|
||||
if request.user.groups.filter(name="view_all_results").exists():
|
||||
view_all_results = True
|
||||
@@ -200,7 +209,6 @@ def exam_scores_cid_user(request, pk, sk, passcode):
|
||||
# Get user answer
|
||||
user_answer = q.cid_user_answers.filter(cid=cid).first()
|
||||
|
||||
|
||||
if user_answer is None:
|
||||
answer_score = 0
|
||||
ans = ""
|
||||
@@ -229,7 +237,7 @@ def exam_scores_cid_user(request, pk, sk, passcode):
|
||||
{
|
||||
"exam": exam,
|
||||
"cid": cid,
|
||||
"passcode" : passcode,
|
||||
"passcode": passcode,
|
||||
"questions": questions,
|
||||
"answers": answers,
|
||||
"answers_marks": answers_marks,
|
||||
@@ -254,6 +262,7 @@ def exam_start(request, pk):
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def exam_finish(request, pk, cid, passcode):
|
||||
exam = get_object_or_404(Exam, pk=pk)
|
||||
|
||||
@@ -262,8 +271,7 @@ def exam_finish(request, pk, cid, passcode):
|
||||
|
||||
questions = exam.exam_questions.all()
|
||||
|
||||
answers = CidUserAnswer.objects.filter(
|
||||
cid=cid, exam=exam)
|
||||
answers = CidUserAnswer.objects.filter(cid=cid, exam=exam)
|
||||
|
||||
answer_question_map = {}
|
||||
for ans in answers:
|
||||
@@ -311,8 +319,7 @@ def exam_take(request, pk, sk, cid, passcode):
|
||||
|
||||
pos = exam.get_question_index(question)
|
||||
|
||||
answer = question.cid_user_answers.filter(
|
||||
cid=cid, exam=exam).first()
|
||||
answer = question.cid_user_answers.filter(cid=cid, exam=exam).first()
|
||||
|
||||
if request.method == "POST":
|
||||
if answer:
|
||||
@@ -336,7 +343,9 @@ def exam_take(request, pk, sk, cid, passcode):
|
||||
elif "finish" in request.POST:
|
||||
return redirect("sbas:exam_finish", **kwargs)
|
||||
elif "goto" in request.POST:
|
||||
return redirect("sbas:exam_take", sk=int(request.POST.get("goto")), **kwargs)
|
||||
return redirect(
|
||||
"sbas:exam_take", sk=int(request.POST.get("goto")), **kwargs
|
||||
)
|
||||
else:
|
||||
form = CidUserAnswerForm(instance=answer)
|
||||
|
||||
@@ -351,7 +360,6 @@ def exam_take(request, pk, sk, cid, passcode):
|
||||
if answer is not None:
|
||||
saved_answer = answer.answer
|
||||
|
||||
|
||||
return render(
|
||||
request,
|
||||
"sbas/exam_take.html",
|
||||
@@ -373,7 +381,11 @@ def exam_take(request, pk, sk, cid, passcode):
|
||||
def loadJsonAnswer(answer):
|
||||
pass
|
||||
|
||||
SbasExamViews = ExamViews(Exam, Question, CidUserAnswer, "sbas", "sbas", loadJsonAnswer)
|
||||
|
||||
GenericExamViews = ExamViews(
|
||||
Exam, Question, CidUserAnswer, "sbas", "sbas", loadJsonAnswer
|
||||
)
|
||||
|
||||
|
||||
class QuestionView(LoginRequiredMixin, SingleTableMixin, FilterView):
|
||||
model = Question
|
||||
@@ -382,6 +394,7 @@ class QuestionView(LoginRequiredMixin, SingleTableMixin, FilterView):
|
||||
|
||||
filterset_class = QuestionFilter
|
||||
|
||||
|
||||
class UserAnswerView(LoginRequiredMixin, DetailView):
|
||||
model = CidUserAnswer
|
||||
|
||||
@@ -399,8 +412,9 @@ class UserAnswerDelete(SuperuserRequiredMixin, DeleteView):
|
||||
template_name = "user_answer_delete.html"
|
||||
success_url = reverse_lazy("sbas:user_answer_table_view")
|
||||
|
||||
#@user_passes_test(lambda u: u.is_superuser)
|
||||
#def user_answer_delete_multiple(request):
|
||||
|
||||
# @user_passes_test(lambda u: u.is_superuser)
|
||||
# def user_answer_delete_multiple(request):
|
||||
# if request.is_ajax():
|
||||
# print(request.POST["answer_ids"])
|
||||
# answer_ids = json.loads(request.POST["answer_ids"])
|
||||
@@ -412,4 +426,4 @@ class UserAnswerDelete(SuperuserRequiredMixin, DeleteView):
|
||||
# return JsonResponse({"status": "error"})
|
||||
|
||||
|
||||
GenericViews = GenericViewBase("sbas", Question, CidUserAnswer, Exam)
|
||||
GenericViews = GenericViewBase("sbas", Question, CidUserAnswer, Exam)
|
||||
|
||||
Reference in New Issue
Block a user