add user_user support to atlas collections
This commit is contained in:
+10
-4
@@ -28,6 +28,7 @@ from atlas.models import (
|
|||||||
Condition,
|
Condition,
|
||||||
Structure,
|
Structure,
|
||||||
Subspecialty,
|
Subspecialty,
|
||||||
|
UserReportAnswer,
|
||||||
)
|
)
|
||||||
|
|
||||||
from anatomy.models import Modality
|
from anatomy.models import Modality
|
||||||
@@ -440,10 +441,8 @@ SeriesImageFormSet = inlineformset_factory(
|
|||||||
max_num=2000,
|
max_num=2000,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class BaseReportAnswerForm(ModelForm):
|
||||||
class CidReportAnswerForm(ModelForm):
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CidReportAnswer
|
|
||||||
fields = ["answer"]
|
fields = ["answer"]
|
||||||
|
|
||||||
widgets = {
|
widgets = {
|
||||||
@@ -460,9 +459,16 @@ class CidReportAnswerForm(ModelForm):
|
|||||||
# }
|
# }
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(CidReportAnswerForm, self).__init__(*args, **kwargs)
|
super(BaseReportAnswerForm, self).__init__(*args, **kwargs)
|
||||||
self.fields["answer"].required = False
|
self.fields["answer"].required = False
|
||||||
|
|
||||||
|
class CidReportAnswerForm(BaseReportAnswerForm):
|
||||||
|
class Meta(BaseReportAnswerForm.Meta):
|
||||||
|
model = CidReportAnswer
|
||||||
|
|
||||||
|
class UserReportAnswerForm(BaseReportAnswerForm):
|
||||||
|
class Meta(BaseReportAnswerForm.Meta):
|
||||||
|
model = UserReportAnswer
|
||||||
|
|
||||||
class CidReportAnswerMarkForm(ModelForm):
|
class CidReportAnswerMarkForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|||||||
@@ -542,6 +542,16 @@ class BaseReportAnswer(models.Model):
|
|||||||
def get_answer_score(self):
|
def get_answer_score(self):
|
||||||
return self.score
|
return self.score
|
||||||
|
|
||||||
|
def set_cid_or_user(self, cid=None, user=None):
|
||||||
|
if cid is not None:
|
||||||
|
self.cid = cid
|
||||||
|
elif user is not None:
|
||||||
|
self.user = user
|
||||||
|
else:
|
||||||
|
raise ValueError("No cid or user specified")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
<h2>{{collection.name}}
|
<h2>{{collection.name}}
|
||||||
<h2>Start: {{exam.name}}</h2>
|
<h2>Start: {{exam.name}}</h2>
|
||||||
|
|
||||||
|
{% if request.user.is_authenticated and valid_user %}
|
||||||
|
<a href="{% url 'atlas:collection_case_view_take_user' pk=collection.pk case_number=0 %}">Start</a>
|
||||||
|
{% else %}
|
||||||
Enter your CID and passcode in the below boxes.<br />
|
Enter your CID and passcode in the below boxes.<br />
|
||||||
<p><input id="cid-box" type="text" value="Candidate ID"></p>
|
<p><input id="cid-box" type="text" value="Candidate ID"></p>
|
||||||
<p><input id="passcode-box" type="text" value="Passcode"></p>
|
<p><input id="passcode-box" type="text" value="Passcode"></p>
|
||||||
@@ -45,5 +48,6 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
{% if cid is not None %}
|
||||||
CID: {{cid}}
|
CID: {{cid}}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<h2>Collection: {{collection.name}}</h2>
|
<h2>Collection: {{collection.name}}</h2>
|
||||||
|
|
||||||
@@ -10,7 +12,19 @@
|
|||||||
<div class="sba-finish-list">
|
<div class="sba-finish-list">
|
||||||
<ul>
|
<ul>
|
||||||
{% for question, answer in question_answer_tuples %}
|
{% for question, answer in question_answer_tuples %}
|
||||||
<li><a href="{% url 'atlas:collection_case_view_take' pk=collection.id case_number=forloop.counter0 cid=cid passcode=passcode %}"><button {% if not answer %}class="unanswered"{% endif %}>{{forloop.counter}}: {{answer.answer}}</button></a></li>
|
<li>
|
||||||
|
<a href="
|
||||||
|
{% if cid is not None %}
|
||||||
|
{% url 'atlas:collection_case_view_take' pk=collection.id case_number=forloop.counter0 cid=cid passcode=passcode %}
|
||||||
|
{% else %}
|
||||||
|
{% url 'atlas:collection_case_view_take_user' pk=collection.id case_number=forloop.counter0 %}
|
||||||
|
{% endif %}
|
||||||
|
">
|
||||||
|
<span {% if not answer %}class="unanswered"{% endif %}>Case: {{forloop.counter}}</span>
|
||||||
|
</a>
|
||||||
|
<br/>
|
||||||
|
{{answer.answer}}
|
||||||
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+11
-1
@@ -71,10 +71,15 @@ urlpatterns = [
|
|||||||
name="collection_scores_cid",
|
name="collection_scores_cid",
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
"collection/<int:pk>/take/<int:cid>/<str:passcode>",
|
"collection/<int:pk>/take_overview/<int:cid>/<str:passcode>",
|
||||||
views.collection_take_overview,
|
views.collection_take_overview,
|
||||||
name="collection_take_overview",
|
name="collection_take_overview",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"collection/<int:pk>/take_overview",
|
||||||
|
views.collection_take_overview_user,
|
||||||
|
name="collection_take_overview_user",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"collection/<int:pk>/<int:case_number>",
|
"collection/<int:pk>/<int:case_number>",
|
||||||
views.collection_case_view,
|
views.collection_case_view,
|
||||||
@@ -85,6 +90,11 @@ urlpatterns = [
|
|||||||
views.collection_case_view_take,
|
views.collection_case_view_take,
|
||||||
name="collection_case_view_take",
|
name="collection_case_view_take",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"collection/<int:pk>/<int:case_number>/take/",
|
||||||
|
views.collection_case_view_take_user,
|
||||||
|
name="collection_case_view_take_user",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"collection/<int:pk>/<int:case_number>/review",
|
"collection/<int:pk>/<int:case_number>/review",
|
||||||
views.collection_case_view_review,
|
views.collection_case_view_review,
|
||||||
|
|||||||
+88
-52
@@ -44,6 +44,7 @@ from .forms import (
|
|||||||
SeriesFindingForm,
|
SeriesFindingForm,
|
||||||
CaseDifferentialFormSet,
|
CaseDifferentialFormSet,
|
||||||
StructureForm,
|
StructureForm,
|
||||||
|
UserReportAnswerForm,
|
||||||
)
|
)
|
||||||
from .models import (
|
from .models import (
|
||||||
Case,
|
Case,
|
||||||
@@ -60,6 +61,7 @@ from .models import (
|
|||||||
Subspecialty,
|
Subspecialty,
|
||||||
SeriesFinding,
|
SeriesFinding,
|
||||||
SeriesImage,
|
SeriesImage,
|
||||||
|
UserReportAnswer,
|
||||||
)
|
)
|
||||||
from .tables import (
|
from .tables import (
|
||||||
CaseCollectionTable,
|
CaseCollectionTable,
|
||||||
@@ -371,7 +373,6 @@ class CaseCollectionCreate(RevisionMixin, LoginRequiredMixin, CreateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
|
||||||
self.object = form.save(commit=False)
|
self.object = form.save(commit=False)
|
||||||
self.object.save()
|
self.object.save()
|
||||||
|
|
||||||
@@ -421,7 +422,6 @@ class SeriesCreate(RevisionMixin, LoginRequiredMixin, CreateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
|
||||||
self.object = form.save(commit=False)
|
self.object = form.save(commit=False)
|
||||||
self.object.save()
|
self.object.save()
|
||||||
|
|
||||||
@@ -528,7 +528,6 @@ class SeriesUpdate(
|
|||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
|
||||||
self.object = form.save(commit=False)
|
self.object = form.save(commit=False)
|
||||||
self.object.save()
|
self.object.save()
|
||||||
|
|
||||||
@@ -613,7 +612,6 @@ class AtlasCreateBase(RevisionMixin, LoginRequiredMixin):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
|
||||||
self.object = form.save(commit=False)
|
self.object = form.save(commit=False)
|
||||||
|
|
||||||
# Add exam objects
|
# Add exam objects
|
||||||
@@ -653,12 +651,12 @@ class AtlasCreate(AtlasCreateBase, CreateView):
|
|||||||
|
|
||||||
return initial
|
return initial
|
||||||
## There has to be a better way...
|
## There has to be a better way...
|
||||||
#try:
|
# try:
|
||||||
# s = (i.pk for i in self.request.user.atlas_default.site.all())
|
# s = (i.pk for i in self.request.user.atlas_default.site.all())
|
||||||
# self.initial.update({"site": s})
|
# self.initial.update({"site": s})
|
||||||
#except AttributeError:
|
# except AttributeError:
|
||||||
# pass
|
# pass
|
||||||
#return self.initial
|
# return self.initial
|
||||||
|
|
||||||
|
|
||||||
class AtlasUpdate(
|
class AtlasUpdate(
|
||||||
@@ -701,7 +699,6 @@ class AtlasUpdate(
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
|
||||||
self.object = form.save(commit=False)
|
self.object = form.save(commit=False)
|
||||||
self.object.save()
|
self.object.save()
|
||||||
|
|
||||||
@@ -722,24 +719,30 @@ class AtlasUpdate(
|
|||||||
else:
|
else:
|
||||||
return super().form_invalid(form)
|
return super().form_invalid(form)
|
||||||
|
|
||||||
|
|
||||||
def add_collection_to_case_form(request, case_id):
|
def add_collection_to_case_form(request, case_id):
|
||||||
if request.method == 'POST':
|
if request.method == "POST":
|
||||||
form = AddCollectionToCaseForm(request.POST, user=request.user)
|
form = AddCollectionToCaseForm(request.POST, user=request.user)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
case = get_object_or_404(Case, pk=case_id)
|
case = get_object_or_404(Case, pk=case_id)
|
||||||
|
|
||||||
case.casecollection_set.add(*form.cleaned_data["casecollection"])
|
case.casecollection_set.add(*form.cleaned_data["casecollection"])
|
||||||
#do_something_with_form_data(form.cleaned_data)
|
# do_something_with_form_data(form.cleaned_data)
|
||||||
return HttpResponse("Done")
|
return HttpResponse("Done")
|
||||||
return render(request, 'web/htmx_contact_form_confirm.html')
|
return render(request, "web/htmx_contact_form_confirm.html")
|
||||||
else:
|
else:
|
||||||
form = AddCollectionToCaseForm(user=request.user)
|
form = AddCollectionToCaseForm(user=request.user)
|
||||||
return render(request, 'generic_form.html', {
|
return render(
|
||||||
'form': form,
|
request,
|
||||||
'target_url': reverse("atlas:case_collection_form", args=(case_id,))
|
"generic_form.html",
|
||||||
})
|
{
|
||||||
|
"form": form,
|
||||||
|
"target_url": reverse("atlas:case_collection_form", args=(case_id,)),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
#class AddCollectionToCaseView(FormView):
|
|
||||||
|
# class AddCollectionToCaseView(FormView):
|
||||||
# form_class = AddCollectionToCaseForm
|
# form_class = AddCollectionToCaseForm
|
||||||
# template_name = "generic_form.html"
|
# template_name = "generic_form.html"
|
||||||
#
|
#
|
||||||
@@ -756,6 +759,7 @@ def add_collection_to_case_form(request, case_id):
|
|||||||
# pk = self.kwargs["pk"]
|
# pk = self.kwargs["pk"]
|
||||||
# return reverse("atlas:case_detail", kwargs={"pk": pk})
|
# return reverse("atlas:case_detail", kwargs={"pk": pk})
|
||||||
|
|
||||||
|
|
||||||
class AtlasClone(AtlasCreateBase, CreateView):
|
class AtlasClone(AtlasCreateBase, CreateView):
|
||||||
"""Clones a existing atlas"""
|
"""Clones a existing atlas"""
|
||||||
|
|
||||||
@@ -1085,18 +1089,26 @@ def collection_detail(request, pk):
|
|||||||
|
|
||||||
cases = collection.cases.all().order_by("casedetail__sort_order")
|
cases = collection.cases.all().order_by("casedetail__sort_order")
|
||||||
|
|
||||||
return render(request, "atlas/collection_detail.html", {"collection": collection, "cases": cases})
|
return render(
|
||||||
|
request,
|
||||||
|
"atlas/collection_detail.html",
|
||||||
|
{"collection": collection, "cases": cases},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def collection_take(request, pk):
|
def collection_take(request, pk):
|
||||||
collection = get_object_or_404(CaseCollection, pk=pk)
|
collection = get_object_or_404(CaseCollection, pk=pk)
|
||||||
|
|
||||||
|
template_variables = {
|
||||||
|
"collection": collection,
|
||||||
|
"valid_user": collection.check_logged_in_user(request),
|
||||||
|
}
|
||||||
|
|
||||||
match collection.collection_type:
|
match collection.collection_type:
|
||||||
case "REP":
|
case "REP":
|
||||||
return render(request, "atlas/collection_take.html", {"collection": collection})
|
return render(request, "atlas/collection_take.html", template_variables)
|
||||||
case "REV":
|
case "REV":
|
||||||
return render(request, "atlas/collection_review.html", {"collection": collection})
|
return render(request, "atlas/collection_review.html", template_variables)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@user_is_collection_author_or_atlas_editor
|
@user_is_collection_author_or_atlas_editor
|
||||||
@@ -1234,7 +1246,13 @@ def exam_cids(request, pk):
|
|||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
|
|
||||||
def collection_take_overview(request, pk, cid, passcode):
|
def collection_take_overview_user(request, pk):
|
||||||
|
return collection_take_overview(request, pk)
|
||||||
|
|
||||||
|
|
||||||
|
def collection_take_overview(
|
||||||
|
request, pk: int, cid: int | None = None, passcode: str | None = None
|
||||||
|
):
|
||||||
collection = get_object_or_404(CaseCollection, pk=pk)
|
collection = get_object_or_404(CaseCollection, pk=pk)
|
||||||
|
|
||||||
if not collection.active:
|
if not collection.active:
|
||||||
@@ -1246,7 +1264,11 @@ def collection_take_overview(request, pk, cid, passcode):
|
|||||||
cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related()
|
cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related()
|
||||||
|
|
||||||
case_details = CaseDetail.objects.filter(case__in=cases, collection=collection)
|
case_details = CaseDetail.objects.filter(case__in=cases, collection=collection)
|
||||||
|
|
||||||
|
if cid is not None:
|
||||||
answers = CidReportAnswer.objects.filter(cid=cid, question__in=case_details)
|
answers = CidReportAnswer.objects.filter(cid=cid, question__in=case_details)
|
||||||
|
else:
|
||||||
|
answers = UserReportAnswer.objects.filter(user=request.user, question__in=case_details)
|
||||||
|
|
||||||
answer_question_map = {}
|
answer_question_map = {}
|
||||||
for ans in answers:
|
for ans in answers:
|
||||||
@@ -1261,8 +1283,7 @@ def collection_take_overview(request, pk, cid, passcode):
|
|||||||
else:
|
else:
|
||||||
question_answer_tuples.append((q, None))
|
question_answer_tuples.append((q, None))
|
||||||
|
|
||||||
c = CidUser.objects.filter(cid=cid).first()
|
cid_user_exam = collection.get_or_create_cid_user_exam(cid=cid, user_user=request.user)
|
||||||
cid_user_exam = collection.get_or_create_cid_user_exam(cid_user=c)
|
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -1278,14 +1299,22 @@ def collection_take_overview(request, pk, cid, passcode):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def collection_case_view_review(request, pk: int, case_number: int):
|
def collection_case_view_review(request, pk: int, case_number: int):
|
||||||
return collection_case_view_take(request, pk, case_number, None, None)
|
return collection_case_view_take(request, pk, case_number, None, None)
|
||||||
|
|
||||||
def collection_case_view_take(request, pk: int, case_number: int, cid=None, passcode=None):
|
|
||||||
|
def collection_case_view_take_user(request, pk: int, case_number: int):
|
||||||
|
return collection_case_view_take(request, pk, case_number)
|
||||||
|
|
||||||
|
|
||||||
|
def collection_case_view_take(
|
||||||
|
request, pk: int, case_number: int, cid=None, passcode=None
|
||||||
|
):
|
||||||
collection = get_object_or_404(CaseCollection, pk=pk)
|
collection = get_object_or_404(CaseCollection, pk=pk)
|
||||||
|
|
||||||
form = None
|
form = None
|
||||||
answer = None
|
answer: CidReportAnswer | UserReportAnswer
|
||||||
|
|
||||||
if collection.collection_type != collection.COLLECTION_TYPE_CHOICES.REVIEW:
|
if collection.collection_type != collection.COLLECTION_TYPE_CHOICES.REVIEW:
|
||||||
if not collection.active:
|
if not collection.active:
|
||||||
@@ -1294,32 +1323,36 @@ def collection_case_view_take(request, pk: int, case_number: int, cid=None, pass
|
|||||||
if cid is not None and not collection.check_cid_user(cid, passcode, request):
|
if cid is not None and not collection.check_cid_user(cid, passcode, request):
|
||||||
raise Http404("Error accessing exam")
|
raise Http404("Error accessing exam")
|
||||||
|
|
||||||
|
cid_user_exam = collection.get_or_create_cid_user_exam(
|
||||||
if cid is not None:
|
cid=cid, user_user=request.user
|
||||||
c = CidUser.objects.filter(cid=cid).first()
|
)
|
||||||
cid_user_exam = collection.get_or_create_cid_user_exam(cid_user=c)
|
|
||||||
else:
|
|
||||||
cid_user_exam = collection.get_or_create_cid_user_exam(user_user=request.user)
|
|
||||||
|
|
||||||
cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related()
|
cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related()
|
||||||
case = cases[case_number]
|
case = cases[case_number]
|
||||||
|
|
||||||
if collection.collection_type == "REP":
|
if collection.collection_type == "REP":
|
||||||
c = CidUser.objects.filter(cid=cid).first()
|
cid_user_exam = collection.get_or_create_cid_user_exam(
|
||||||
cid_user_exam = collection.get_or_create_cid_user_exam(cid_user=c)
|
cid=cid, user_user=request.user
|
||||||
|
)
|
||||||
case_detail = CaseDetail.objects.get(case=case, collection=collection)
|
case_detail = CaseDetail.objects.get(case=case, collection=collection)
|
||||||
|
|
||||||
|
if cid is not None:
|
||||||
answer = case_detail.cidreportanswer_set.filter(cid=cid).first()
|
answer = case_detail.cidreportanswer_set.filter(cid=cid).first()
|
||||||
|
ReportAnswerForm = CidReportAnswerForm
|
||||||
|
else:
|
||||||
|
answer = case_detail.userreportanswer_set.filter(user=request.user).first()
|
||||||
|
ReportAnswerForm = UserReportAnswerForm
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
if collection.collection_type == "REP":
|
if collection.collection_type == "REP":
|
||||||
if not collection.publish_results:
|
if not collection.publish_results:
|
||||||
if answer:
|
if answer:
|
||||||
form = CidReportAnswerForm(request.POST, instance=answer)
|
form = ReportAnswerForm(request.POST, instance=answer)
|
||||||
else:
|
else:
|
||||||
form = CidReportAnswerForm(request.POST)
|
form = ReportAnswerForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
answer = form.save(commit=False)
|
answer = form.save(commit=False)
|
||||||
answer.cid = cid
|
answer.set_cid_or_user(cid=cid, user=request.user)
|
||||||
answer.question = case_detail
|
answer.question = case_detail
|
||||||
# answer.published_date = timezone.now()
|
# answer.published_date = timezone.now()
|
||||||
answer.save()
|
answer.save()
|
||||||
@@ -1327,24 +1360,25 @@ def collection_case_view_take(request, pk: int, case_number: int, cid=None, pass
|
|||||||
cid_user_exam.end_time = timezone.now()
|
cid_user_exam.end_time = timezone.now()
|
||||||
cid_user_exam.save()
|
cid_user_exam.save()
|
||||||
|
|
||||||
|
if cid is not None:
|
||||||
kwargs = {"pk": pk, "cid": cid, "passcode": passcode}
|
kwargs = {"pk": pk, "cid": cid, "passcode": passcode}
|
||||||
redirect_url = "atlas:collection_case_view_take"
|
redirect_url = "atlas:collection_case_view_take"
|
||||||
|
overview_url = "atlas:collection_take_overview"
|
||||||
|
else:
|
||||||
|
kwargs = {"pk": pk}
|
||||||
|
redirect_url = "atlas:collection_case_view_take_user"
|
||||||
|
overview_url = "atlas:collection_take_overview_user"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
kwargs = {"pk": pk}
|
kwargs = {"pk": pk}
|
||||||
redirect_url = "atlas:collection_case_view_review"
|
redirect_url = "atlas:collection_case_view_review"
|
||||||
|
|
||||||
if "next" in request.POST:
|
if "next" in request.POST:
|
||||||
return redirect(
|
return redirect(redirect_url, case_number=case_number + 1, **kwargs)
|
||||||
redirect_url, case_number=case_number + 1, **kwargs
|
|
||||||
)
|
|
||||||
elif "previous" in request.POST:
|
elif "previous" in request.POST:
|
||||||
return redirect(
|
return redirect(redirect_url, case_number=case_number - 1, **kwargs)
|
||||||
redirect_url, case_number=case_number - 1, **kwargs
|
|
||||||
)
|
|
||||||
elif "finish" in request.POST:
|
elif "finish" in request.POST:
|
||||||
redirect_url = "atlas:collection_take"
|
return redirect(overview_url, **kwargs)
|
||||||
return redirect(redirect_url, **kwargs)
|
|
||||||
elif "goto" in request.POST:
|
elif "goto" in request.POST:
|
||||||
return redirect(
|
return redirect(
|
||||||
redirect_url,
|
redirect_url,
|
||||||
@@ -1352,7 +1386,8 @@ def collection_case_view_take(request, pk: int, case_number: int, cid=None, pass
|
|||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
form = CidReportAnswerForm(instance=answer)
|
if collection.collection_type == "REP":
|
||||||
|
form = ReportAnswerForm(instance=answer)
|
||||||
|
|
||||||
series_list = case.series.all().prefetch_related("images", "examination", "plane")
|
series_list = case.series.all().prefetch_related("images", "examination", "plane")
|
||||||
|
|
||||||
@@ -1431,6 +1466,7 @@ def collection_case_view(request, pk, case_number):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@user_is_collection_author_or_atlas_editor
|
@user_is_collection_author_or_atlas_editor
|
||||||
def delete_collection_cid_answers(request, exam_id, cid):
|
def delete_collection_cid_answers(request, exam_id, cid):
|
||||||
collection = get_object_or_404(CaseCollection, pk=exam_id)
|
collection = get_object_or_404(CaseCollection, pk=exam_id)
|
||||||
@@ -1441,17 +1477,18 @@ def delete_collection_cid_answers(request, exam_id, cid):
|
|||||||
case__in=cases, collection=collection
|
case__in=cases, collection=collection
|
||||||
).prefetch_related("case")
|
).prefetch_related("case")
|
||||||
|
|
||||||
cid_user_answers = CidReportAnswer.objects.filter(question__in=case_details, cid=cid)
|
cid_user_answers = CidReportAnswer.objects.filter(
|
||||||
|
question__in=case_details, cid=cid
|
||||||
|
)
|
||||||
|
|
||||||
temp = {}
|
temp = {}
|
||||||
for ans in cid_user_answers:
|
for ans in cid_user_answers:
|
||||||
temp[ans.pk] = (ans.question.pk, ans.score, ans.cid, ans.answer)
|
temp[ans.pk] = (ans.question.pk, ans.score, ans.cid, ans.answer)
|
||||||
ans.delete()
|
ans.delete()
|
||||||
|
|
||||||
|
|
||||||
return JsonResponse(temp)
|
return JsonResponse(temp)
|
||||||
|
|
||||||
|
|
||||||
@user_is_collection_author_or_atlas_editor
|
@user_is_collection_author_or_atlas_editor
|
||||||
def delete_collection_answers(request, exam_id):
|
def delete_collection_answers(request, exam_id):
|
||||||
collection = get_object_or_404(CaseCollection, pk=exam_id)
|
collection = get_object_or_404(CaseCollection, pk=exam_id)
|
||||||
@@ -1464,15 +1501,14 @@ def delete_collection_answers(request, exam_id):
|
|||||||
|
|
||||||
cid_user_answers = CidReportAnswer.objects.filter(question__in=case_details)
|
cid_user_answers = CidReportAnswer.objects.filter(question__in=case_details)
|
||||||
|
|
||||||
|
|
||||||
temp = {}
|
temp = {}
|
||||||
for ans in cid_user_answers:
|
for ans in cid_user_answers:
|
||||||
temp[ans.pk] = (ans.question.pk, ans.score, ans.cid, ans.answer)
|
temp[ans.pk] = (ans.question.pk, ans.score, ans.cid, ans.answer)
|
||||||
ans.delete()
|
ans.delete()
|
||||||
|
|
||||||
|
|
||||||
return JsonResponse(temp)
|
return JsonResponse(temp)
|
||||||
|
|
||||||
|
|
||||||
# TODO: this needs a major cleanup
|
# TODO: this needs a major cleanup
|
||||||
@user_is_collection_author_or_atlas_editor
|
@user_is_collection_author_or_atlas_editor
|
||||||
def collection_scores_cid(request, pk):
|
def collection_scores_cid(request, pk):
|
||||||
@@ -1541,7 +1577,6 @@ def collection_scores_cid(request, pk):
|
|||||||
user_scores = {}
|
user_scores = {}
|
||||||
user_scores_normalised = {}
|
user_scores_normalised = {}
|
||||||
for user in user_answers_marks:
|
for user in user_answers_marks:
|
||||||
|
|
||||||
user_scores[user] = sum(
|
user_scores[user] = sum(
|
||||||
[i for i in user_answers_marks[user] if (i != "unmarked" and i != None)]
|
[i for i in user_answers_marks[user] if (i != "unmarked" and i != None)]
|
||||||
)
|
)
|
||||||
@@ -1587,7 +1622,7 @@ def collection_scores_cid(request, pk):
|
|||||||
collection.stats_min = min(user_scores_list)
|
collection.stats_min = min(user_scores_list)
|
||||||
collection.stats_max = max(user_scores_list)
|
collection.stats_max = max(user_scores_list)
|
||||||
|
|
||||||
#collection.stats_graph = fig_html
|
# collection.stats_graph = fig_html
|
||||||
|
|
||||||
collection.user_scores = user_scores
|
collection.user_scores = user_scores
|
||||||
|
|
||||||
@@ -1619,6 +1654,7 @@ def collection_scores_cid(request, pk):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
GenericExamViews = ExamViews(
|
GenericExamViews = ExamViews(
|
||||||
CaseCollection, Case, None, CidReportAnswer, "atlas", "casecollection"
|
CaseCollection, Case, None, CidReportAnswer, "atlas", "casecollection"
|
||||||
)
|
)
|
||||||
+6
-2
@@ -470,12 +470,14 @@ class ExamCollectionGenericBase(models.Model):
|
|||||||
if c:
|
if c:
|
||||||
return c
|
return c
|
||||||
|
|
||||||
if user_user is not None:
|
elif user_user is not None:
|
||||||
c = CidUserExam.objects.filter(
|
c = CidUserExam.objects.filter(
|
||||||
content_type=content_type, object_id=self.pk, user_user=user_user
|
content_type=content_type, object_id=self.pk, user_user=user_user
|
||||||
).first()
|
).first()
|
||||||
if c:
|
if c:
|
||||||
return c
|
return c
|
||||||
|
else:
|
||||||
|
raise ValueError("Invalid cid / cid_user / user_user")
|
||||||
|
|
||||||
if start_time is None:
|
if start_time is None:
|
||||||
start_time = timezone.now()
|
start_time = timezone.now()
|
||||||
@@ -488,13 +490,15 @@ class ExamCollectionGenericBase(models.Model):
|
|||||||
start_time=start_time,
|
start_time=start_time,
|
||||||
)
|
)
|
||||||
|
|
||||||
if user_user is not None:
|
elif user_user is not None:
|
||||||
new = CidUserExam(
|
new = CidUserExam(
|
||||||
content_type=content_type,
|
content_type=content_type,
|
||||||
object_id=self.pk,
|
object_id=self.pk,
|
||||||
user_user=user_user,
|
user_user=user_user,
|
||||||
start_time=start_time,
|
start_time=start_time,
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
raise ValueError("Invalid cid / cid_user / user_user")
|
||||||
|
|
||||||
new.save()
|
new.save()
|
||||||
return new
|
return new
|
||||||
|
|||||||
+5
-11
@@ -235,11 +235,7 @@ def exam_take_overview(request, pk, cid=None, passcode=None):
|
|||||||
else:
|
else:
|
||||||
question_answer_tuples.append((q, None))
|
question_answer_tuples.append((q, None))
|
||||||
|
|
||||||
if cid is not None:
|
cid_user_exam = exam.get_or_create_cid_user_exam(cid=cid, user_user=request.user)
|
||||||
c = CidUser.objects.filter(cid=cid).first()
|
|
||||||
cid_user_exam = exam.get_or_create_cid_user_exam(cid_user=c)
|
|
||||||
else:
|
|
||||||
cid_user_exam = exam.get_or_create_cid_user_exam(user_user=request.user)
|
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -256,7 +252,7 @@ def exam_take_overview(request, pk, cid=None, passcode=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def exam_take(request, pk: int, sk: int, cid: str = None, passcode: str = None):
|
def exam_take(request, pk: int, sk: int, cid: str| None = None, passcode: str| None = None):
|
||||||
exam = get_object_or_404(Exam, pk=pk)
|
exam = get_object_or_404(Exam, pk=pk)
|
||||||
|
|
||||||
if not exam.active:
|
if not exam.active:
|
||||||
@@ -265,11 +261,9 @@ def exam_take(request, pk: int, sk: int, cid: str = None, passcode: str = None):
|
|||||||
if not exam.check_cid_user(cid, passcode, request):
|
if not exam.check_cid_user(cid, passcode, request):
|
||||||
raise Http404("Error accessing exam")
|
raise Http404("Error accessing exam")
|
||||||
|
|
||||||
if cid is not None:
|
print(cid, passcode, request.user)
|
||||||
c = CidUser.objects.filter(cid=cid).first()
|
|
||||||
cid_user_exam = exam.get_or_create_cid_user_exam(cid_user=c)
|
cid_user_exam = exam.get_or_create_cid_user_exam(cid=cid, user_user=request.user)
|
||||||
else:
|
|
||||||
cid_user_exam = exam.get_or_create_cid_user_exam(user_user=request.user)
|
|
||||||
|
|
||||||
question = exam.exam_questions.all()[sk]
|
question = exam.exam_questions.all()[sk]
|
||||||
|
|
||||||
|
|||||||
+3
-11
@@ -202,11 +202,7 @@ def exam_take_overview(request, pk, cid=None, passcode=None):
|
|||||||
else:
|
else:
|
||||||
question_answer_tuples.append((q, None))
|
question_answer_tuples.append((q, None))
|
||||||
|
|
||||||
if cid is not None:
|
cid_user_exam = exam.get_or_create_cid_user_exam(cid=cid, user_user=request.user)
|
||||||
c = CidUser.objects.filter(cid=cid).first()
|
|
||||||
cid_user_exam = exam.get_or_create_cid_user_exam(cid_user=c)
|
|
||||||
else:
|
|
||||||
cid_user_exam = exam.get_or_create_cid_user_exam(user_user=request.user)
|
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -223,7 +219,7 @@ def exam_take_overview(request, pk, cid=None, passcode=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def exam_take(request, pk: int, sk: int, cid: str = None, passcode: str = None):
|
def exam_take(request, pk: int, sk: int, cid: int = None, passcode: str = None):
|
||||||
exam = get_object_or_404(Exam, pk=pk)
|
exam = get_object_or_404(Exam, pk=pk)
|
||||||
|
|
||||||
if not exam.active:
|
if not exam.active:
|
||||||
@@ -232,11 +228,7 @@ def exam_take(request, pk: int, sk: int, cid: str = None, passcode: str = None):
|
|||||||
if not exam.check_cid_user(cid, passcode, request):
|
if not exam.check_cid_user(cid, passcode, request):
|
||||||
raise Http404("Error accessing exam")
|
raise Http404("Error accessing exam")
|
||||||
|
|
||||||
if cid is not None:
|
cid_user_exam = exam.get_or_create_cid_user_exam(cid = cid, user_user=request.user)
|
||||||
c = CidUser.objects.filter(cid=cid).first()
|
|
||||||
cid_user_exam = exam.get_or_create_cid_user_exam(cid_user=c)
|
|
||||||
else:
|
|
||||||
cid_user_exam = exam.get_or_create_cid_user_exam(user_user=request.user)
|
|
||||||
|
|
||||||
question = exam.exam_questions.all()[sk]
|
question = exam.exam_questions.all()[sk]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user