.
This commit is contained in:
+1
-1
@@ -1054,7 +1054,7 @@ def collection_detail_view(request, pk):
|
|||||||
def collection_case_view(request, pk, case_number):
|
def collection_case_view(request, pk, case_number):
|
||||||
collection = get_object_or_404(CaseCollection, pk=pk)
|
collection = get_object_or_404(CaseCollection, pk=pk)
|
||||||
|
|
||||||
cases = collection.cases.all().prefetch_related()
|
cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related()
|
||||||
case = cases[case_number]
|
case = cases[case_number]
|
||||||
|
|
||||||
series_list = case.series.all().prefetch_related("images", "examination", "plane")
|
series_list = case.series.all().prefetch_related("images", "examination", "plane")
|
||||||
|
|||||||
@@ -128,6 +128,10 @@ class ExamBase(models.Model):
|
|||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
def save(self, *args, recreate_json=True, **kwargs):
|
||||||
|
self.recreate_json = recreate_json
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
def get_exam_stats(self):
|
def get_exam_stats(self):
|
||||||
text = f"""{self.name}
|
text = f"""{self.name}
|
||||||
{"-"*len(self.name)}
|
{"-"*len(self.name)}
|
||||||
|
|||||||
@@ -10,6 +10,14 @@
|
|||||||
|
|
||||||
{% include 'exam_notes.html' %}
|
{% include 'exam_notes.html' %}
|
||||||
|
|
||||||
|
{% if exam.recreate_json %}
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
Exam JSON is out of date.
|
||||||
|
|
||||||
|
<a href="{% url app_name|add:':exam_json_recreate' pk=exam.pk %}">Click here to force refresh</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
This exam has {{question_number}} questions. Time limit: {{exam.time_limit}} seconds.
|
This exam has {{question_number}} questions. Time limit: {{exam.time_limit}} seconds.
|
||||||
|
|
||||||
Exam mode: {{ exam.exam_mode }}<br />
|
Exam mode: {{ exam.exam_mode }}<br />
|
||||||
|
|||||||
+41
-19
@@ -1,5 +1,6 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import statistics
|
import statistics
|
||||||
|
import threading
|
||||||
from dal import autocomplete
|
from dal import autocomplete
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
@@ -425,7 +426,13 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
exam.recreate_json = True
|
exam.recreate_json = True
|
||||||
exam.save()
|
exam.save()
|
||||||
|
|
||||||
exam.get_exam_json()
|
# exam.get_exam_json()
|
||||||
|
|
||||||
|
# TODO: check if mememory leak?
|
||||||
|
t = threading.Thread(target=self.exam_json,
|
||||||
|
args=(request, pk))
|
||||||
|
t.setDaemon(True)
|
||||||
|
t.start()
|
||||||
|
|
||||||
return redirect("{}:exam_overview".format(self.app_name), pk=pk)
|
return redirect("{}:exam_overview".format(self.app_name), pk=pk)
|
||||||
|
|
||||||
@@ -559,8 +566,11 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
request,
|
request,
|
||||||
f"{self.app_name}/base.html",
|
f"{self.app_name}/base.html",
|
||||||
{
|
{
|
||||||
"simple_content": format_html("""Answer scores updated <br/>
|
"simple_content": format_html(
|
||||||
<a href='{}'>Return</a>""", reverse(f"{self.app_name}:exam_scores_cid", kwargs={"pk": exam.pk}))
|
"""Answer scores updated <br/>
|
||||||
|
<a href='{}'>Return</a>""",
|
||||||
|
reverse(f"{self.app_name}:exam_scores_cid", kwargs={"pk": exam.pk}),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -746,9 +756,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
question_unmarked_map = []
|
question_unmarked_map = []
|
||||||
for q in questions:
|
for q in questions:
|
||||||
count = int(q.get_unmarked_user_answer_count(exam_pk=exam.pk))
|
count = int(q.get_unmarked_user_answer_count(exam_pk=exam.pk))
|
||||||
question_unmarked_map.append(
|
question_unmarked_map.append((q, count, count))
|
||||||
(q, count, count)
|
|
||||||
)
|
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -955,7 +963,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
exam.recreate_json = False
|
exam.recreate_json = False
|
||||||
|
|
||||||
exam.json_creation_time = time
|
exam.json_creation_time = time
|
||||||
exam.save()
|
exam.save(recreate_json=False)
|
||||||
|
|
||||||
# We also try to clear the cache of any associated questions (longs)
|
# We also try to clear the cache of any associated questions (longs)
|
||||||
# see exam_question_json
|
# see exam_question_json
|
||||||
@@ -1304,6 +1312,7 @@ class ExaminationAutocomplete(autocomplete.Select2QuerySetView):
|
|||||||
|
|
||||||
return qs
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class CidUserExamView(CidManagerRequiredMixin, SingleTableMixin, FilterView):
|
class CidUserExamView(CidManagerRequiredMixin, SingleTableMixin, FilterView):
|
||||||
model = CidUser
|
model = CidUser
|
||||||
table_class = CidUserExamTable
|
table_class = CidUserExamTable
|
||||||
@@ -1336,6 +1345,7 @@ class CidUserExamView(CidManagerRequiredMixin, SingleTableMixin, FilterView):
|
|||||||
context["exams"] = True
|
context["exams"] = True
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class CidUserView(CidManagerRequiredMixin, SingleTableMixin, FilterView):
|
class CidUserView(CidManagerRequiredMixin, SingleTableMixin, FilterView):
|
||||||
model = CidUser
|
model = CidUser
|
||||||
table_class = CidUserTable
|
table_class = CidUserTable
|
||||||
@@ -1385,6 +1395,7 @@ def group_view(request):
|
|||||||
{"groups": groups},
|
{"groups": groups},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@user_is_cid_user_manager
|
@user_is_cid_user_manager
|
||||||
def group_view(request):
|
def group_view(request):
|
||||||
groups = CidUserGroup.objects.filter(archive=False)
|
groups = CidUserGroup.objects.filter(archive=False)
|
||||||
@@ -1395,6 +1406,7 @@ def group_view(request):
|
|||||||
{"groups": groups, "view_all": False},
|
{"groups": groups, "view_all": False},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@user_is_cid_user_manager
|
@user_is_cid_user_manager
|
||||||
def group_view_all(request):
|
def group_view_all(request):
|
||||||
groups = CidUserGroup.objects.filter()
|
groups = CidUserGroup.objects.filter()
|
||||||
@@ -1411,6 +1423,7 @@ def group_view_all(request):
|
|||||||
def group_email_resend(request, pk):
|
def group_email_resend(request, pk):
|
||||||
return group_email(request, pk, resend=True)
|
return group_email(request, pk, resend=True)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@user_is_cid_user_manager
|
@user_is_cid_user_manager
|
||||||
def group_email_results_resend(request, pk):
|
def group_email_results_resend(request, pk):
|
||||||
@@ -1430,24 +1443,24 @@ def group_email(request, pk, resend=False):
|
|||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"generic/group_emailed.html",
|
"generic/group_emailed.html",
|
||||||
#{"sent": sent, "not_sent": not_sent, "users_count": users.count()},
|
# {"sent": sent, "not_sent": not_sent, "users_count": users.count()},
|
||||||
{"users": users, "users_count": users.count()},
|
{"users": users, "users_count": users.count()},
|
||||||
)
|
)
|
||||||
|
|
||||||
#sent = []
|
# sent = []
|
||||||
#not_sent = []
|
# not_sent = []
|
||||||
#for u in users:
|
# for u in users:
|
||||||
# success, msg = u.email_details(resend=resend)
|
# success, msg = u.email_details(resend=resend)
|
||||||
# if success:
|
# if success:
|
||||||
# sent.append(u)
|
# sent.append(u)
|
||||||
# else:
|
# else:
|
||||||
# not_sent.append((u, msg))
|
# not_sent.append((u, msg))
|
||||||
|
|
||||||
#return render(
|
# return render(
|
||||||
# request,
|
# request,
|
||||||
# "generic/group_emailed.html",
|
# "generic/group_emailed.html",
|
||||||
# {"sent": sent, "not_sent": not_sent, "users_count": users.count()},
|
# {"sent": sent, "not_sent": not_sent, "users_count": users.count()},
|
||||||
#)
|
# )
|
||||||
|
|
||||||
|
|
||||||
@user_is_cid_user_manager
|
@user_is_cid_user_manager
|
||||||
@@ -1457,11 +1470,13 @@ def group_email_results(request, pk, resend=False):
|
|||||||
if resend:
|
if resend:
|
||||||
users = group.ciduser_set.filter(active=True, internal_candidate=True)
|
users = group.ciduser_set.filter(active=True, internal_candidate=True)
|
||||||
else:
|
else:
|
||||||
users = group.ciduser_set.filter(active=True, internal_candidate=True, results_email_sent=False)
|
users = group.ciduser_set.filter(
|
||||||
|
active=True, internal_candidate=True, results_email_sent=False
|
||||||
|
)
|
||||||
|
|
||||||
#sent = []
|
# sent = []
|
||||||
#not_sent = []
|
# not_sent = []
|
||||||
#for u in users:
|
# for u in users:
|
||||||
# success, msg = u.email_results(resend=resend)
|
# success, msg = u.email_results(resend=resend)
|
||||||
# if success:
|
# if success:
|
||||||
# sent.append(u)
|
# sent.append(u)
|
||||||
@@ -1471,18 +1486,22 @@ def group_email_results(request, pk, resend=False):
|
|||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"generic/group_emailed.html",
|
"generic/group_emailed.html",
|
||||||
#{"sent": sent, "not_sent": not_sent, "users_count": users.count()},
|
# {"sent": sent, "not_sent": not_sent, "users_count": users.count()},
|
||||||
{"users": users, "users_count": users.count()},
|
{"users": users, "users_count": users.count()},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@user_is_cid_user_manager
|
@user_is_cid_user_manager
|
||||||
def candidate_email_results(request, cid, resend=False):
|
def candidate_email_results(request, cid, resend=False):
|
||||||
user = CidUser.objects.get(cid=cid)
|
user = CidUser.objects.get(cid=cid)
|
||||||
|
|
||||||
email_sent, comment = user.email_results(additional_emails=["priya.suresh@nhs.net"], resend=True)
|
email_sent, comment = user.email_results(
|
||||||
|
additional_emails=["priya.suresh@nhs.net"], resend=True
|
||||||
|
)
|
||||||
|
|
||||||
return JsonResponse({"sent": email_sent, "comment": comment})
|
return JsonResponse({"sent": email_sent, "comment": comment})
|
||||||
|
|
||||||
|
|
||||||
@user_is_cid_user_manager
|
@user_is_cid_user_manager
|
||||||
def candidate_email_results_resend(request, cid, resend=True):
|
def candidate_email_results_resend(request, cid, resend=True):
|
||||||
return candidate_email_results(request, cid, resend=True)
|
return candidate_email_results(request, cid, resend=True)
|
||||||
@@ -1637,14 +1656,17 @@ class CidUserCreate(RevisionMixin, CidManagerRequiredMixin, CreateView):
|
|||||||
model = CidUser
|
model = CidUser
|
||||||
form_class = CidUserForm
|
form_class = CidUserForm
|
||||||
|
|
||||||
|
|
||||||
class CidUserUpdate(RevisionMixin, CidManagerRequiredMixin, UpdateView):
|
class CidUserUpdate(RevisionMixin, CidManagerRequiredMixin, UpdateView):
|
||||||
model = CidUser
|
model = CidUser
|
||||||
form_class = CidUserForm
|
form_class = CidUserForm
|
||||||
|
|
||||||
|
|
||||||
class CidUserGroupCreate(RevisionMixin, CidManagerRequiredMixin, CreateView):
|
class CidUserGroupCreate(RevisionMixin, CidManagerRequiredMixin, CreateView):
|
||||||
model = CidUserGroup
|
model = CidUserGroup
|
||||||
form_class = CidUserGroupForm
|
form_class = CidUserGroupForm
|
||||||
|
|
||||||
|
|
||||||
class CidUserGroupUpdate(RevisionMixin, CidManagerRequiredMixin, UpdateView):
|
class CidUserGroupUpdate(RevisionMixin, CidManagerRequiredMixin, UpdateView):
|
||||||
model = CidUserGroup
|
model = CidUserGroup
|
||||||
form_class = CidUserGroupForm
|
form_class = CidUserGroupForm
|
||||||
|
|||||||
Reference in New Issue
Block a user