continue unifying views

This commit is contained in:
Ross
2021-02-07 22:43:17 +00:00
parent 3712cf15fc
commit 8fbb50ee9f
12 changed files with 330 additions and 752 deletions
+35
View File
@@ -15,6 +15,9 @@ import string
from generic.models import Examination, ExamBase
from collections import defaultdict
from helpers.images import image_as_base64
image_storage = FileSystemStorage(
# Physical file location ROOT
location=u"{0}/anatomy/".format(settings.MEDIA_ROOT),
@@ -273,6 +276,38 @@ class Exam(ExamBase):
help_text="Exam time limit (in seconds)", default=5400
)
def get_exam_json(self):
questions = self.exam_questions.all()
exam_questions = defaultdict(dict)
exam_order = []
for q in questions:
exam_order.append(q.id)
exam_questions[q.id] = {
"title": "{}".format(q.description),
"question": str(q.question_type),
"images": [image_as_base64(q.image)],
"annotations": [str(q.image_annotations)],
"type": "anatomy",
}
exam_json = {
"eid": "anatomy/{}".format(self.id),
"cached": False,
"exam_type": "anatomy",
"exam_name": self.name,
"exam_mode": True,
"exam_order": exam_order,
"questions": exam_questions,
}
if self.time_limit:
exam_json["exam_time"] = self.time_limit
return exam_json
# class UserAnswer(models.Model):
+6 -6
View File
@@ -5,7 +5,7 @@ app_name = "anatomy"
urlpatterns = [
# path('', views.question_list, name='question_list'),
path("", views.index, name="index"),
path("", views.AnatomyExamViews.index, name="index"),
path("question/", views.AnatomyQuestionView.as_view(), name="anatomy_question_view"),
path("question/<int:pk>/", views.question_detail, name="question_detail"),
path("question/create/", views.AnatomyQuestionCreate.as_view(), name="anatomy_question_create"),
@@ -16,21 +16,21 @@ urlpatterns = [
name="answer_question"),
path("question/<int:pk>/clone", views.QuestionClone.as_view(), name="question_clone"),
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>/mark", views.AnatomyExamViews.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.exam_question_detail, name="exam_question_detail"),
path("exam/<int:pk>/question/<int:sk>/", views.AnatomyExamViews.exam_question_detail, name="exam_question_detail"),
path("exam/<int:pk>/", views.AnatomyExamViews.exam_overview, name="exam_overview"),
path("exam/<int:pk>/json_edit", views.exam_json_edit, name="exam_json_edit"),
path("exam/<int:pk>/json_edit", views.AnatomyExamViews.exam_json_edit, name="exam_json_edit"),
path("exam/<int:pk>/scores", views.exam_scores_cid,
name="exam_scores_cid"),
path("exam/<int:pk>/scores/<int:sk>/", views.exam_scores_cid_user,
name="exam_scores_cid_user"),
path("exam/<int:pk>/toggle_active", views.AnatomyExamViews.exam_toggle_active, name="exam_toggle_active"),
path("exam/<int:pk>/toggle_results_published", views.AnatomyExamViews.exam_toggle_results_published, name="exam_toggle_results_published"),
path("exam/submit", views.postExamAnswers, name="exam_answers_submit"),
path("exam/submit", views.AnatomyExamViews.postExamAnswers, name="exam_answers_submit"),
path("exam/", views.AnatomyExamViews.exam_list, name="exam_list"),
path("exam/json/", views.AnatomyExamViews.active_exams, name="active_exams"),
path("exam/json/<int:pk>", views.exam_json, name="exam_json"),
path("exam/json/<int:pk>", views.AnatomyExamViews.exam_json, name="exam_json"),
path("exam/json/<int:pk>/recreate", views.AnatomyExamViews.exam_json_recreate, name="exam_json_recreate"),
#path("cid/<int:pk>", views.cid_scores, name="cid_scores"),
#path("cid/", views.cid_selector, name="cid_selector"),
+25 -205
View File
@@ -75,17 +75,12 @@ def user_is_admin(user):
return False
def question_list(request):
questions = AnatomyQuestion.objects.all()
return render(request, "anatomy/question_list.html", {"questions": questions})
@login_required
def index(request):
exams = Exam.objects.all()
return render(request, "anatomy/index.html", {"exams": exams})
@login_required
def question_detail(request, pk):
question = get_object_or_404(AnatomyQuestion, pk=pk)
@@ -93,38 +88,6 @@ def question_detail(request, pk):
return render(request, "anatomy/question_detail.html", {"question": question})
@login_required
def exam_question_detail(request, pk, sk):
exam = get_object_or_404(Exam, pk=pk)
question = exam.exam_questions.all()[sk]
exam_length = len(exam.exam_questions.all())
pos = exam.get_question_index(question) + 1
print(question.exams.through.sort_value)
previous = -1
if sk > 0:
previous = sk - 1
next = sk + 1
if sk == exam_length - 1:
next = False
return render(
request,
"anatomy/question_detail.html",
{
"question": question,
"exam": exam,
"next": next,
"previous": previous,
"exam_length": exam_length,
"pos": pos,
},
)
@login_required
def answer_question(request, pk):
@@ -283,63 +246,28 @@ def loadJsonAnswer(answer):
return True
def exam_json_edit(request, pk):
if request.is_ajax() and request.method == "POST":
exam = get_object_or_404(Exam, pk=pk)
if request.POST.get("set_open_access") == "true":
state = True
else:
state = False
questions_changed = []
for q in exam.exam_questions.all():
q.open_access = state
q.save()
questions_changed.append(q.pk)
data = {"status": "success", "questions": questions_changed, "state": state}
return JsonResponse(data, status=200)
else:
data = {"status": "error"}
return JsonResponse(data, status=400)
@csrf_exempt
def postExamAnswers(request):
if request.is_ajax and request.method == "POST":
n = 0
# horrible but it works
#for k in request.POST.dict():
for answer in json.loads(request.POST.get("answers")):
ret = loadJsonAnswer(answer)
if ret is not True:
return ret
n = n + 1
# print(UserAnswer.objects.filter(exam__id=q["eid"]))
# print(request.urlencode())
return JsonResponse({"success": True, "question_count": n})
return JsonResponse({"success": False, "error": "Invalid data"})
# return render(request, "anatomy/exam.html", {"exam" : exam, "question" : question})
# @user_passes_test(user_is_admin, login_url="/accounts/login")
@login_required
def mark_overview(request, pk):
exam = get_object_or_404(Exam, pk=pk)
questions = exam.exam_questions.all()
return render(
request, "anatomy/mark_overview.html", {"exam": exam, "questions": questions}
)
#@csrf_exempt
#def postExamAnswers(request):
# if request.is_ajax and request.method == "POST":
#
# n = 0
# # horrible but it works
# #for k in request.POST.dict():
#
# for answer in json.loads(request.POST.get("answers")):
# ret = loadJsonAnswer(answer)
#
# if ret is not True:
# return ret
# n = n + 1
#
# # print(UserAnswer.objects.filter(exam__id=q["eid"]))
# # print(request.urlencode())
#
# return JsonResponse({"success": True, "question_count": n})
# return JsonResponse({"success": False, "error": "Invalid data"})
#
# # return render(request, "anatomy/exam.html", {"exam" : exam, "question" : question})
# @user_passes_test(user_is_admin, login_url="/accounts/login")
@@ -487,116 +415,6 @@ def mark(request, pk, sk):
},
)
AnatomyExamViews = ExamViews(Exam, "anatomy", "anatomy")
# def exam_toggle_results_published(request, pk):
# if request.is_ajax() and request.method == "POST":
#
# exam = get_object_or_404(Exam, pk=pk)
#
# exam.publish_results = (
# True if request.POST.get("publish_results") == "true" else False
# )
# exam.save()
# data = {"status": "success", "publish_results": exam.publish_results}
# return JsonResponse(data, status=200)
# else:
# data = {"status": "error"}
# return JsonResponse(data, status=400)
#
#
# def exam_toggle_active(request, pk):
# if request.is_ajax() and request.method == "POST":
#
# exam = get_object_or_404(Exam, pk=pk)
#
# exam.active = True if request.POST.get("active") == "true" else False
# exam.save()
# data = {"status": "success", "active": exam.active}
# return JsonResponse(data, status=200)
# else:
# data = {"status": "error"}
# return JsonResponse(data, status=400)
#
#
# def active_exams(request, json=True):
# exams = Exam.objects.all()
#
# active_exams = {"exams": []}
#
# for exam in exams:
# if exam.active:
# active_exams["exams"].append(
# {
# "name": exam.get_exam_name(),
# "url": request.build_absolute_uri(exam.get_json_url()),
# "type": "anatomy",
# }
# )
#
# if json == False:
# return active_exams["exams"]
#
# return JsonResponse(active_exams)
#
# @login_required
# def exam_json_recreate(request, pk):
# exam = get_object_or_404(Exam, pk=pk)
#
# exam.recreate_json = True
# exam.save()
#
# return redirect("anatomy:exam_overview", pk=pk)
def exam_json(request, pk):
exam = get_object_or_404(Exam, pk=pk)
if not exam.active:
raise Http404("No available exam")
exam_json_cache = cache.get("anatomy_exam_json_{}".format(pk))
if exam_json_cache is not None and not exam.recreate_json:
exam_json_cache["cached"] = True
return JsonResponse(exam_json_cache)
questions = exam.exam_questions.all()
exam_questions = defaultdict(dict)
exam_order = []
for q in questions:
exam_order.append(q.id)
exam_questions[q.id] = {
"title": "{}".format(q.description),
"question": str(q.question_type),
"images": [image_as_base64(q.image)],
"annotations": [str(q.image_annotations)],
"type": "anatomy",
}
exam_json = {
"eid": "anatomy/{}".format(exam.id),
"cached": False,
"exam_type": "anatomy",
"exam_name": exam.name,
"exam_mode": True,
"exam_order": exam_order,
"questions": exam_questions,
}
if exam.time_limit:
exam_json["exam_time"] = exam.time_limit
exam.recreate_json = False
exam.save()
cache.set("anatomy_exam_json_{}".format(pk), exam_json, 3600)
return JsonResponse(exam_json)
@login_required
@@ -1116,3 +934,5 @@ def question_save_annotation(request, pk):
data = {"status": "error"}
return JsonResponse(data, status=400)
AnatomyExamViews = ExamViews(Exam, "anatomy", "anatomy", loadJsonAnswer)
+152 -29
View File
@@ -6,8 +6,18 @@ from django.views.decorators.csrf import csrf_exempt
from django.http import Http404, JsonResponse
from django.http import HttpResponseRedirect, HttpResponse
from django.contrib.auth.mixins import LoginRequiredMixin
from django.utils.decorators import method_decorator
from django.core.cache import cache
import json
from django.views import View
from .forms import (
ExaminationForm,
)
@@ -40,12 +50,15 @@ def get_examination_id(request):
return HttpResponse("/")
class ExamViews:
def __init__(self, exam, app, question_type):
class ExamViews(View, LoginRequiredMixin):
def __init__(self, exam, app, question_type, loadJsonAnswer):
self.Exam = exam
self.app_name = app
self.question_type = question_type
self.loadJsonAnswer = loadJsonAnswer
@method_decorator(login_required)
def exam_toggle_results_published(self, request, pk):
if request.is_ajax() and request.method == "POST":
@@ -62,6 +75,7 @@ class ExamViews:
return JsonResponse(data, status=400)
@method_decorator(login_required)
def exam_toggle_active(self, request, pk):
if request.is_ajax() and request.method == "POST":
@@ -75,6 +89,105 @@ class ExamViews:
data = {"status": "error"}
return JsonResponse(data, status=400)
@method_decorator(login_required)
def exam_json_recreate(self, request, pk):
exam = get_object_or_404(self.Exam, pk=pk)
exam.recreate_json = True
exam.save()
return redirect("{}:exam_overview".format(self.app_name), pk=pk)
@method_decorator(login_required)
def exam_list(self, request):
exams = self.Exam.objects.all()
return render(request, "{}/exam_list.html".format(self.app_name), {"exams": exams})
@method_decorator(login_required)
def exam_overview(self, request, pk):
#print(Exam.objects.all())
#exams = Exam.objects.all()
#print("test", Exam.objects.all().get(id=pk))
exam = get_object_or_404(self.Exam, pk=pk)
questions = exam.exam_questions.all()
question_number = len(questions)
return render(
request,
"{}/exam_overview.html".format(self.app_name),
{"exam": exam, "questions": questions, "question_number": question_number},
)
@method_decorator(login_required)
def exam_json_edit(self, request, pk):
if request.is_ajax() and request.method == "POST":
exam = get_object_or_404(self.Exam, pk=pk)
if request.POST.get("set_open_access") == "true":
state = True
else:
state = False
questions_changed = []
for q in exam.exam_questions.all():
q.open_access = state
q.save()
questions_changed.append(q.pk)
data = {"status": "success", "questions": questions_changed, "state": state}
return JsonResponse(data, status=200)
else:
data = {"status": "error"}
return JsonResponse(data, status=400)
@method_decorator(login_required)
def mark_overview(self, request, pk):
exam = get_object_or_404(self.Exam, pk=pk)
questions = exam.exam_questions.all()
return render(
request, "{}/mark_overview.html".format(self.app_name), {"exam": exam, "questions": questions}
)
@method_decorator(login_required)
def index(self, request):
exams = self.Exam.objects.all()
return render(request, "{}/index.html".format(self.app_name), {"exams": exams})
@method_decorator(login_required)
def exam_question_detail(self, request, pk, sk):
exam = get_object_or_404(self.Exam, pk=pk)
question = exam.exam_questions.all()[sk]
exam_length = len(exam.exam_questions.all())
pos = exam.get_question_index(question) + 1
previous = -1
if sk > 0:
previous = sk - 1
next = sk + 1
if sk == exam_length - 1:
next = False
return render(
request,
"{}/question_detail.html".format(self.app_name),
{
"question": question,
"exam": exam,
"next": next,
"previous": previous,
"exam_length": exam_length,
"pos": pos,
},
)
def active_exams(self, request, json=True):
exams = self.Exam.objects.all()
@@ -96,35 +209,45 @@ class ExamViews:
return JsonResponse(active_exams)
@login_required
def exam_json_recreate(self, request, pk):
@method_decorator(csrf_exempt)
def postExamAnswers(request):
if request.is_ajax and request.method == "POST":
n = 0
for answer in json.loads(request.POST.get("answers")):
ret = self.loadJsonAnswer(answer)
#if ret is not True:
# return ret
if ret:
n = n + 1
# print(UserAnswer.objects.filter(exam__id=q["eid"]))
# print(request.urlencode())
return JsonResponse({"success": True, "question_count": n})
return JsonResponse({"success": False, "error": "Invalid data"})
def exam_json(self, request, pk):
exam = get_object_or_404(self.Exam, pk=pk)
exam.recreate_json = True
if not exam.active:
raise Http404("No available exam")
exam_json_cache = cache.get("{}_exam_json_{}".format(self.app_name, pk))
if exam_json_cache is not None and not exam.recreate_json:
exam_json_cache["cached"] = True
return JsonResponse(exam_json_cache)
exam_json = exam.get_exam_json()
exam.recreate_json = False
exam.save()
return redirect("{}:exam_overview".format(self.app_name), pk=pk)
@login_required
def exam_list(self, request):
exams = self.Exam.objects.all()
return render(request, "{}/exam_list.html".format(self.app_name), {"exams": exams})
@login_required
def exam_overview(self, request, pk):
#print(Exam.objects.all())
#exams = Exam.objects.all()
#print("test", Exam.objects.all().get(id=pk))
exam = get_object_or_404(self.Exam, pk=pk)
questions = exam.exam_questions.all()
question_number = len(questions)
return render(
request,
"{}/exam_overview.html".format(self.app_name),
{"exam": exam, "questions": questions, "question_number": question_number},
)
cache.set("{}_exam_json_{}".format(self.app_name, pk), exam_json, 3600)
return JsonResponse(exam_json)
+66 -40
View File
@@ -5,64 +5,90 @@ app_name = "longs"
urlpatterns = [
# path('', views.question_list, name='question_list'),
path("", views.index, name="index"),
path("", views.LongExamViews.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"),
path("series/", views.LongSeriesView.as_view(), name="long_series_view"),
path("series/<int:pk>", views.long_series_detail, name="long_series_detail"),
#path("unchecked/", views.unchecked_list, name="unchecked_list"),
#path("verified/<int:pk>/", views.verified_detail, name="verified_detail"),
# path("unchecked/", views.unchecked_list, name="unchecked_list"),
# path("verified/<int:pk>/", views.verified_detail, name="verified_detail"),
path("question/<int:pk>/", views.long_detail, name="long_detail"),
path("question/<int:pk>/split", views.long_split, name="long_split"),
path("question/<int:pk>/clone", views.LongClone.as_view(), name="long_clone"),
#path("verified/", views.verified, name="verified"),
#path("all_questions/", views.all_questions, name="all_questions"),
# path("verified/", views.verified, name="verified"),
# path("all_questions/", views.all_questions, name="all_questions"),
path("question/<int:pk>/scrap", views.long_scrap, name="long_scrap"),
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>/", views.exam_take, name="exam_take"),
path("exam/<int:pk>/question/<int:sk>/", views.exam_question_detail, name="exam_question_detail"),
path("exam/<int:pk>/", views.exam_overview, name="exam_overview"),
path("exam/<int:pk>/json_edit", views.exam_json_edit, name="exam_json_edit"),
path("exam/<int:pk>/scores", views.exam_scores_cid,
name="exam_scores_cid"),
path("exam/<int:pk>/scores/<int:sk>/", views.exam_scores_cid_user,
name="exam_scores_cid_user"),
path("exam/<int:pk>/toggle_active", views.exam_toggle_active, name="exam_toggle_active"),
path("exam/<int:pk>/toggle_results_published", views.exam_toggle_results_published, name="exam_toggle_results_published"),
path("exam/submit", views.postExamAnswers, name="exam_answers_submit"),
path("exam/", views.exam_list, name="exam_list"),
path("exam/json/", views.active_exams, name="active_exams"),
path("exam/<int:pk>/mark", views.LongExamViews.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,
name="exam_question_detail",
),
path("exam/<int:pk>/", views.LongExamViews.exam_overview, name="exam_overview"),
path("exam/<int:pk>/json_edit", views.LongExamViews.exam_json_edit, name="exam_json_edit"),
path("exam/<int:pk>/scores", views.exam_scores_cid, name="exam_scores_cid"),
path(
"exam/<int:pk>/scores/<int:sk>/",
views.exam_scores_cid_user,
name="exam_scores_cid_user",
),
path(
"exam/<int:pk>/toggle_active",
views.LongExamViews.exam_toggle_active,
name="exam_toggle_active",
),
path(
"exam/<int:pk>/toggle_results_published",
views.LongExamViews.exam_toggle_results_published,
name="exam_toggle_results_published",
),
path("exam/submit", views.LongExamViews.postExamAnswers, name="exam_answers_submit"),
path("exam/", views.LongExamViews.exam_list, name="exam_list"),
path("exam/json/", views.LongExamViews.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(
"exam/json/<int:pk>/recreate",
views.LongExamViews.exam_json_recreate,
name="exam_json_recreate",
),
path("create/", views.LongCreate.as_view(), name="long_create"),
path("create/series", views.LongSeriesCreate.as_view(), name="long_series_create"),
path("create/series/<int:pk>", views.LongSeriesCreate.as_view(), name="long_series_id_create"),
path("create/defaults",
views.LongCreationDefaultView.as_view(),
name="long_create_defaults"),
path(
"create/series/<int:pk>",
views.LongSeriesCreate.as_view(),
name="long_series_id_create",
),
path(
"create/defaults",
views.LongCreationDefaultView.as_view(),
name="long_create_defaults",
),
path("region/create/", views.create_region, name="create_region"),
path("region/ajax/get_region_id",
views.get_region_id,
name="get_region_id"),
path("abnormality/create/",
views.create_abnormality,
name="create_abnormality"),
path("abnormality/ajax/get_abnormality_id",
views.get_abnormality_id,
name="get_abnormality_id"),
path("examination/create/",
views.create_examination,
name="create_examination"),
path("examination/ajax/get_examination_id",
views.get_examination_id,
name="get_examination_id"),
path("region/ajax/get_region_id", views.get_region_id, name="get_region_id"),
path("abnormality/create/", views.create_abnormality, name="create_abnormality"),
path(
"abnormality/ajax/get_abnormality_id",
views.get_abnormality_id,
name="get_abnormality_id",
),
path("examination/create/", views.create_examination, name="create_examination"),
path(
"examination/ajax/get_examination_id",
views.get_examination_id,
name="get_examination_id",
),
path(
"question/<int:pk>/update",
views.LongUpdate.as_view(),
name="long_update",
),
path("series/<int:pk>/update", views.LongSeriesUpdate.as_view(), name="long_series_update"),
path(
"series/<int:pk>/update",
views.LongSeriesUpdate.as_view(),
name="long_series_update",
),
path("<int:pk>/add_note", views.AddNote.as_view(), name="long_add_note"),
]
+4 -178
View File
@@ -56,6 +56,8 @@ from django.forms.models import model_to_dict
from longs.forms import LongCreationDefaultForm
from longs.models import LongCreationDefault
from generic.views import ExamViews
logger = logging.getLogger(__name__)
@@ -69,11 +71,6 @@ class AuthorOrCheckerRequiredMixin(object):
return obj
@login_required
def index(request):
exams = Exam.objects.all()
return render(request, "longs/index.html", {"exams": exams})
# def index(request):
# other_longs = Long.objects.exclude(author=request.user.pk)
@@ -652,62 +649,6 @@ def loadJsonAnswer(answer):
return True
def exam_json_edit(request, pk):
if request.is_ajax() and request.method == "POST":
exam = get_object_or_404(Exam, pk=pk)
if request.POST.get("set_open_access") == "true":
state = True
else:
state = False
questions_changed = []
for q in exam.exam_questions.all():
q.open_access = state
q.save()
questions_changed.append(q.pk)
data = {"status": "success", "questions": questions_changed, "state": state}
return JsonResponse(data, status=200)
else:
data = {"status": "error"}
return JsonResponse(data, status=400)
@csrf_exempt
def postExamAnswers(request):
if request.is_ajax and request.method == "POST":
n = 0
for answer in json.loads(request.POST.get("answers")):
ret = loadJsonAnswer(answer)
#if ret is not True:
# return ret
if ret:
n = n + 1
# print(UserAnswer.objects.filter(exam__id=q["eid"]))
# print(request.urlencode())
return JsonResponse({"success": True, "question_count": n})
return JsonResponse({"success": False, "error": "Invalid data"})
# @user_passes_test(user_is_admin, login_url="/accounts/login")
@login_required
def mark_overview(request, pk):
exam = get_object_or_404(Exam, pk=pk)
questions = exam.exam_questions.all()
return render(
request, "longs/mark_overview.html", {"exam": exam, "questions": questions}
)
# @user_passes_test(user_is_admin, login_url="/accounts/login")
@login_required
@@ -855,56 +796,6 @@ def mark(request, pk, sk):
)
def exam_toggle_results_published(request, pk):
if request.is_ajax() and request.method == "POST":
exam = get_object_or_404(Exam, pk=pk)
exam.publish_results = (
True if request.POST.get("publish_results") == "true" else False
)
exam.save()
data = {"status": "success", "publish_results": exam.publish_results}
return JsonResponse(data, status=200)
else:
data = {"status": "error"}
return JsonResponse(data, status=400)
def exam_toggle_active(request, pk):
if request.is_ajax() and request.method == "POST":
exam = get_object_or_404(Exam, pk=pk)
exam.active = True if request.POST.get("active") == "true" else False
exam.save()
data = {"status": "success", "active": exam.active}
return JsonResponse(data, status=200)
else:
data = {"status": "error"}
return JsonResponse(data, status=400)
def active_exams(request, json=True):
exams = Exam.objects.all()
active_exams = {"exams": []}
for exam in exams:
if exam.active:
active_exams["exams"].append(
{
"name": exam.get_exam_name(),
"url": request.build_absolute_uri(exam.get_json_url()),
"type": "long",
}
)
if json == False:
return active_exams["exams"]
return JsonResponse(active_exams)
def exam_json(request, pk):
@@ -962,6 +853,7 @@ def exam_json(request, pk):
"questions": exam_questions,
}
if exam.time_limit:
exam_json["exam_time"] = exam.time_limit
@@ -973,16 +865,6 @@ def exam_json(request, pk):
return JsonResponse(exam_json)
@login_required
def exam_json_recreate(request, pk):
exam = get_object_or_404(Exam, pk=pk)
exam.recreate_json = True
exam.save()
return redirect("longs:exam_overview", pk=pk)
@login_required
def exam_scores_cid(request, pk):
exam = get_object_or_404(Exam, pk=pk)
@@ -1155,60 +1037,4 @@ def exam_scores_cid_user(request, pk, sk):
)
@login_required
def exam_question_detail(request, pk, sk):
exam = get_object_or_404(Exam, pk=pk)
question = exam.exam_questions.all()[sk]
exam_length = len(exam.exam_questions.all())
pos = exam.get_question_index(question) + 1
print(question.exams.through.sort_value)
previous = -1
if sk > 0:
previous = sk - 1
next = sk + 1
if sk == exam_length - 1:
next = False
return render(
request,
"longs/long_detail.html",
{
"question": question,
"exam": exam,
"next": next,
"previous": previous,
"exam_length": exam_length,
"pos": pos,
},
)
@login_required
def exam_list(request):
exams = Exam.objects.all()
return render(request, "longs/exam_list.html", {"exams": exams})
@login_required
def exam_overview(request, pk):
print(type(pk))
#print(Exam.objects.all())
#exams = Exam.objects.all()
#print("test", Exam.objects.all().get(id=pk))
exam = get_object_or_404(Exam, pk=pk)
print("exam", exam)
questions = exam.exam_questions.all()
question_number = len(questions)
return render(
request,
"longs/exam_overview.html",
{"exam": exam, "questions": questions, "question_number": question_number},
)
LongExamViews = ExamViews(Exam, "longs", "long", loadJsonAnswer)
+7 -2
View File
@@ -110,7 +110,12 @@
ans: answers
}
postAnswers(ans);
let json = {
eid: {{exam.pk}},
answers: JSON.stringify([ans]),
};
postAnswers(json);
})
});
@@ -125,7 +130,7 @@
function postAnswers(ans) {
console.log(ans);
$.post("{% url 'physics:exam_answers_submit' %}", JSON.stringify(ans)).done((data) => {
$.post("{% url 'physics:exam_answers_submit' %}", ans, null, "json").done((data) => {
console.log(data);
if (data.success) {
let ret = confirm(
+6 -6
View File
@@ -5,7 +5,7 @@ app_name = "physics"
urlpatterns = [
# path('', views.question_list, name='question_list'),
path("", views.index, name="index"),
path("", views.PhysicsExamViews.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"),
@@ -13,15 +13,15 @@ urlpatterns = [
#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", views.exam_take, name="exam_take"),
path("exam/<int:pk>/", views.exam_overview, name="exam_overview"),
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:sk>/", views.exam_scores_cid_user,
name="exam_scores_cid_user"),
path("exam/<int:pk>/toggle_active", views.exam_toggle_active, name="exam_toggle_active"),
path("exam/<int:pk>/toggle_results_published", views.exam_toggle_results_published, name="exam_toggle_results_published"),
path("exam/submit", views.postExamAnswers, name="exam_answers_submit"),
path("exam/", views.exam_list, name="exam_list"),
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/submit", views.PhysicsExamViews.postExamAnswers, name="exam_answers_submit"),
path("exam/", views.PhysicsExamViews.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"),
+4 -82
View File
@@ -31,80 +31,20 @@ import json
import statistics
import plotly.express as px
from generic.views import ExamViews
def question_list(request):
questions = Question.objects.all()
return render(request, "physics/question_list.html", {"questions": questions})
@login_required
def index(request):
exams = Exam.objects.all()
return render(request, "physics/index.html", {"exams": exams})
@login_required
def question_detail(request, pk):
question = get_object_or_404(Question, pk=pk)
return render(request, "physics/question_detail.html", {"question": question})
@login_required
def exam_list(request):
exams = Exam.objects.all()
return render(request, "physics/exam_list.html", {"exams": exams})
@login_required
def exam_overview(request, pk):
print(type(pk))
print(Exam.objects.all())
exams = Exam.objects.all()
print("test", Exam.objects.all().get(id=pk))
exam = get_object_or_404(Exam, pk=pk)
print("exam", exam)
questions = exam.exam_questions.all()
question_number = len(questions)
return render(
request,
"physics/exam_overview.html",
{"exam": exam, "questions": questions, "question_number": question_number},
)
def exam_toggle_results_published(request, pk):
if request.is_ajax() and request.method == "POST":
exam = get_object_or_404(Exam, pk=pk)
exam.publish_results = (
True if request.POST.get("publish_results") == "true" else False
)
exam.save()
data = {"status": "success", "publish_results": exam.publish_results}
return JsonResponse(data, status=200)
else:
data = {"status": "error"}
return JsonResponse(data, status=400)
def exam_toggle_active(request, pk):
if request.is_ajax() and request.method == "POST":
exam = get_object_or_404(Exam, pk=pk)
exam.active = True if request.POST.get("active") == "true" else False
exam.save()
data = {"status": "success", "active": exam.active}
return JsonResponse(data, status=200)
else:
data = {"status": "error"}
return JsonResponse(data, status=400)
def active_exams(request):
exams = Exam.objects.all()
print(exams)
@@ -289,26 +229,6 @@ def exam_take(request, pk):
)
@csrf_exempt
def postExamAnswers(request):
if request.is_ajax and request.method == "POST":
n = 0
# horrible but it works
for k in request.POST.dict():
print(k)
ret = loadJsonAnswer(json.loads(k))
if ret is not True:
return ret
# print(UserAnswer.objects.filter(exam__id=q["eid"]))
# print(request.urlencode())
return JsonResponse({"success": True})
return JsonResponse({"success": False, "error": "Invalid data"})
def loadJsonAnswer(answer):
# As access is not restricted make sure the data appears valid
if (not isinstance(answer["cid"], int)) or (not isinstance(answer["eid"], int)):
@@ -364,3 +284,5 @@ def loadJsonAnswer(answer):
ans.save()
return True
PhysicsExamViews = ExamViews(Exam, "physics", "physics", loadJsonAnswer)
+10 -5
View File
@@ -30,8 +30,9 @@ from anatomy.models import Exam as AnatomyExam
from rapids.models import CidUserAnswer as RapidsCidUserAnswer
from rapids.models import Exam as RapidsExam
from anatomy.views import AnatomyExamViews as AnatomyExamViews, postExamAnswers as postAnatomyExamAnswers
from rapids.views import active_exams as active_rapid_exams, postExamAnswers as postRapidExamAnswers
from anatomy.views import AnatomyExamViews
from rapids.views import RapidExamViews
from longs.views import LongExamViews
@@ -89,11 +90,13 @@ def cid_scores(request, pk):
def active_exams(request):
anatomy_exams = AnatomyExamViews.active_exams(request, False)
rapid_exams = active_rapid_exams(request, False)
rapid_exams = RapidExamViews.active_exams(request, False)
long_exams = LongExamViews.active_exams(request, False)
exams = []
exams.extend(anatomy_exams)
exams.extend(rapid_exams)
exams.extend(long_exams)
active_exams = {"exams": exams}
@@ -107,9 +110,11 @@ def exam_submit(request):
exam_type, exam_id = request.POST.get("eid").split("/")
if exam_type == "anatomy":
return postAnatomyExamAnswers(request)
return AnatomyExamViews.postExamAnswers(request)
elif exam_type == "rapid":
return postRapidExamAnswers(request)
return RapidExamViews.postExamAnswers(request)
elif exam_type == "long":
return LongExamViews.postExamAnswers(request)
return JsonResponse({"success": False, "error": "Invalid exam type"})
# postExamAnswers
+11 -11
View File
@@ -5,7 +5,7 @@ app_name = "rapids"
urlpatterns = [
# path('', views.question_list, name='question_list'),
path("", views.index, name="index"),
path("", views.RapidExamViews.index, name="index"),
path("author/<int:pk>/", views.author_detail, name="author_detail"),
path("author/", views.author_list, name="author_list"),
path("question/", views.RapidView.as_view(), name="rapid_view"),
@@ -18,22 +18,22 @@ urlpatterns = [
#path("all_questions/", views.all_questions, name="all_questions"),
path("question/<int:pk>/scrap", views.rapid_scrap, name="rapid_scrap"),
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>/mark", views.RapidExamViews.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.exam_question_detail, name="exam_question_detail"),
path("exam/<int:pk>/", views.exam_overview, name="exam_overview"),
path("exam/<int:pk>/json_edit", views.exam_json_edit, name="exam_json_edit"),
path("exam/<int:pk>/question/<int:sk>/", views.RapidExamViews.exam_question_detail, name="exam_question_detail"),
path("exam/<int:pk>/", views.RapidExamViews.exam_overview, name="exam_overview"),
path("exam/<int:pk>/json_edit", views.RapidExamViews.exam_json_edit, name="exam_json_edit"),
path("exam/<int:pk>/scores", views.exam_scores_cid,
name="exam_scores_cid"),
path("exam/<int:pk>/scores/<int:sk>/", views.exam_scores_cid_user,
name="exam_scores_cid_user"),
path("exam/<int:pk>/toggle_active", views.exam_toggle_active, name="exam_toggle_active"),
path("exam/<int:pk>/toggle_results_published", views.exam_toggle_results_published, name="exam_toggle_results_published"),
path("exam/submit", views.postExamAnswers, name="exam_answers_submit"),
path("exam/", views.exam_list, name="exam_list"),
path("exam/json/", views.active_exams, name="active_exams"),
path("exam/<int:pk>/toggle_active", views.RapidExamViews.exam_toggle_active, name="exam_toggle_active"),
path("exam/<int:pk>/toggle_results_published", views.RapidExamViews.exam_toggle_results_published, name="exam_toggle_results_published"),
path("exam/submit", views.RapidExamViews.postExamAnswers, name="exam_answers_submit"),
path("exam/", views.RapidExamViews.exam_list, name="exam_list"),
path("exam/json/", views.RapidExamViews.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("exam/json/<int:pk>/recreate", views.RapidExamViews.exam_json_recreate, name="exam_json_recreate"),
path("create/", views.RapidCreate.as_view(), name="rapid_create"),
path("create/defaults",
views.RapidCreationDefaultView.as_view(),
+4 -188
View File
@@ -39,6 +39,9 @@ from .models import (
Answer,
CidUserAnswer,
)
from generic.views import ExamViews
from .tables import RapidTable
from .filters import RapidFilter
@@ -75,20 +78,6 @@ class AuthorOrCheckerRequiredMixin(object):
return obj
@login_required
def index(request):
exams = Exam.objects.all()
return render(request, "rapids/index.html", {"exams": exams})
# def index(request):
# other_rapids = Rapid.objects.exclude(author=request.user.pk)
# user_rapids = Rapid.objects.filter(author=request.user.pk)
# return render(
# request,
# "rapids/index.html",
# {"other_rapids": other_rapids, "user_rapids": user_rapids},
# )
@login_required
@@ -564,63 +553,6 @@ def loadJsonAnswer(answer):
return True
def exam_json_edit(request, pk):
if request.is_ajax() and request.method == "POST":
exam = get_object_or_404(Exam, pk=pk)
if request.POST.get("set_open_access") == "true":
state = True
else:
state = False
questions_changed = []
for q in exam.exam_questions.all():
q.open_access = state
q.save()
questions_changed.append(q.pk)
data = {"status": "success", "questions": questions_changed, "state": state}
return JsonResponse(data, status=200)
else:
data = {"status": "error"}
return JsonResponse(data, status=400)
@csrf_exempt
def postExamAnswers(request):
if request.is_ajax and request.method == "POST":
n = 0
for answer in json.loads(request.POST.get("answers")):
ret = loadJsonAnswer(answer)
#if ret is not True:
# return ret
if ret:
n = n + 1
# print(UserAnswer.objects.filter(exam__id=q["eid"]))
# print(request.urlencode())
return JsonResponse({"success": True, "question_count": n})
return JsonResponse({"success": False, "error": "Invalid data"})
# @user_passes_test(user_is_admin, login_url="/accounts/login")
@login_required
def mark_overview(request, pk):
exam = get_object_or_404(Exam, pk=pk)
questions = exam.exam_questions.all()
return render(
request, "rapids/mark_overview.html", {"exam": exam, "questions": questions}
)
# @user_passes_test(user_is_admin, login_url="/accounts/login")
@login_required
def mark(request, pk, sk):
@@ -767,57 +699,6 @@ def mark(request, pk, sk):
)
def exam_toggle_results_published(request, pk):
if request.is_ajax() and request.method == "POST":
exam = get_object_or_404(Exam, pk=pk)
exam.publish_results = (
True if request.POST.get("publish_results") == "true" else False
)
exam.save()
data = {"status": "success", "publish_results": exam.publish_results}
return JsonResponse(data, status=200)
else:
data = {"status": "error"}
return JsonResponse(data, status=400)
def exam_toggle_active(request, pk):
if request.is_ajax() and request.method == "POST":
exam = get_object_or_404(Exam, pk=pk)
exam.active = True if request.POST.get("active") == "true" else False
exam.save()
data = {"status": "success", "active": exam.active}
return JsonResponse(data, status=200)
else:
data = {"status": "error"}
return JsonResponse(data, status=400)
def active_exams(request, json=True):
exams = Exam.objects.all()
active_exams = {"exams": []}
for exam in exams:
if exam.active:
active_exams["exams"].append(
{
"name": exam.get_exam_name(),
"url": request.build_absolute_uri(exam.get_json_url()),
"type": "rapid",
}
)
if json == False:
return active_exams["exams"]
return JsonResponse(active_exams)
def exam_json(request, pk):
exam = get_object_or_404(Exam, pk=pk)
@@ -885,16 +766,6 @@ def exam_json(request, pk):
return JsonResponse(exam_json)
@login_required
def exam_json_recreate(request, pk):
exam = get_object_or_404(Exam, pk=pk)
exam.recreate_json = True
exam.save()
return redirect("rapids:exam_overview", pk=pk)
@login_required
def exam_scores_cid(request, pk):
exam = get_object_or_404(Exam, pk=pk)
@@ -1067,60 +938,5 @@ def exam_scores_cid_user(request, pk, sk):
)
@login_required
def exam_question_detail(request, pk, sk):
exam = get_object_or_404(Exam, pk=pk)
question = exam.exam_questions.all()[sk]
exam_length = len(exam.exam_questions.all())
pos = exam.get_question_index(question) + 1
print(question.exams.through.sort_value)
previous = -1
if sk > 0:
previous = sk - 1
next = sk + 1
if sk == exam_length - 1:
next = False
return render(
request,
"rapids/rapid_detail.html",
{
"question": question,
"exam": exam,
"next": next,
"previous": previous,
"exam_length": exam_length,
"pos": pos,
},
)
@login_required
def exam_list(request):
exams = Exam.objects.all()
return render(request, "rapids/exam_list.html", {"exams": exams})
@login_required
def exam_overview(request, pk):
print(type(pk))
#print(Exam.objects.all())
#exams = Exam.objects.all()
#print("test", Exam.objects.all().get(id=pk))
exam = get_object_or_404(Exam, pk=pk)
print("exam", exam)
questions = exam.exam_questions.all()
question_number = len(questions)
return render(
request,
"rapids/exam_overview.html",
{"exam": exam, "questions": questions, "question_number": question_number},
)
RapidExamViews = ExamViews(Exam, "rapids", "rapid", loadJsonAnswer)