reoorganise atlas modules
This commit is contained in:
+38
-1
@@ -1,6 +1,8 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
|
|
||||||
|
from django.http import Http404
|
||||||
from rad.settings import REMOTE_URL
|
from rad.settings import REMOTE_URL
|
||||||
from django.db.models.fields.files import ImageField
|
from django.db.models.fields.files import ImageField
|
||||||
from django.db.models.fields.related import ForeignKey
|
from django.db.models.fields.related import ForeignKey
|
||||||
@@ -506,11 +508,46 @@ class CaseCollection(ExamCollectionGenericBase):
|
|||||||
return reverse("atlas:collection_detail", kwargs={"pk": self.pk})
|
return reverse("atlas:collection_detail", kwargs={"pk": self.pk})
|
||||||
|
|
||||||
def get_take_url(self):
|
def get_take_url(self):
|
||||||
return reverse("atlas:collection_take", kwargs={"pk": self.pk})
|
return reverse("atlas:collection_take_start", kwargs={"pk": self.pk})
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
def review_only(self) -> bool:
|
||||||
|
"""Returns True if a users cannot submit responses
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: _description_
|
||||||
|
"""
|
||||||
|
if self.collection_type == self.COLLECTION_TYPE_CHOICES.REVIEW:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_user_can_take(self, cid, passcode, request):
|
||||||
|
"""
|
||||||
|
Helper to check if a user is allowed to access a collection
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cid (_type_): _description_
|
||||||
|
passcode (_type_): _description_
|
||||||
|
request (_type_): _description_
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
Http404: If user does not have access
|
||||||
|
"""
|
||||||
|
if not self.active:
|
||||||
|
raise Http404("Exam not found")
|
||||||
|
|
||||||
|
#if self.collection_is_review():
|
||||||
|
# return True
|
||||||
|
|
||||||
|
#if not self.self_review:
|
||||||
|
|
||||||
|
if not self.check_cid_user(cid, passcode, request):
|
||||||
|
raise Http404("Error accessing exam")
|
||||||
|
|
||||||
|
|
||||||
class CaseDetail(models.Model):
|
class CaseDetail(models.Model):
|
||||||
case = models.ForeignKey(Case, on_delete=models.CASCADE)
|
case = models.ForeignKey(Case, on_delete=models.CASCADE)
|
||||||
|
|||||||
@@ -7,6 +7,12 @@
|
|||||||
: {{case.title}}
|
: {{case.title}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
{% if collection.publish_results or cid_user_exam.completed %}
|
||||||
|
review
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
{% if show_description and case.description %}
|
{% if show_description and case.description %}
|
||||||
@@ -72,7 +78,7 @@
|
|||||||
<form method="POST" class="post-form">{% csrf_token %}
|
<form method="POST" class="post-form">{% csrf_token %}
|
||||||
{% if collection.collection_type == "REP" %}
|
{% if collection.collection_type == "REP" %}
|
||||||
<div class="form-contents">
|
<div class="form-contents">
|
||||||
<fieldset {% if collection.publish_results %}disabled="disabled"{% endif %}>
|
<fieldset {% if collection.publish_results or cid_user_exam.completed %}disabled="disabled"{% endif %}>
|
||||||
{{form}}
|
{{form}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
Publish results: {{collection.publish_results}}<br />
|
Publish results: {{collection.publish_results}}<br />
|
||||||
Active: {{collection.active}}<br />
|
Active: {{collection.active}}<br />
|
||||||
Collection Type: {{collection.collection_type}}<br />
|
Collection Type: {{collection.collection_type}}<br />
|
||||||
|
Self review: {{collection.self_review}}<br />
|
||||||
</div>
|
</div>
|
||||||
<h3>Cases</h3>
|
<h3>Cases</h3>
|
||||||
<ul>
|
<ul>
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
{% extends 'atlas/base.html' %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<h2>{{collection.name}}
|
|
||||||
<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 />
|
|
||||||
<p><input id="cid-box" type="text" value="Candidate ID"></p>
|
|
||||||
<p><input id="passcode-box" type="text" value="Passcode"></p>
|
|
||||||
|
|
||||||
<button>Start</button>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
$(document).ready(function () {
|
|
||||||
window.location.search.substr(1).split("&").forEach((item) =>
|
|
||||||
{
|
|
||||||
s = item.split("=");
|
|
||||||
if (s[0] == "cid") {
|
|
||||||
$("#cid-box").val(s[1]);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (s[0] == "passcode") {
|
|
||||||
$("#passcode-box").val(s[1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
$("#cid-box, #passcode-box").keypress(function(e) {
|
|
||||||
// Enter pressed?
|
|
||||||
console.log(e)
|
|
||||||
if(e.which == 10 || e.which == 13) {
|
|
||||||
$("button").click();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("button").click(() => {
|
|
||||||
let cid = $("#cid-box").val();
|
|
||||||
let passcode = $("#passcode-box").val();
|
|
||||||
|
|
||||||
if (Number.isInteger(parseInt(cid))) {
|
|
||||||
window.location.replace("{% url 'atlas:collection_case_view_take' pk=collection.pk case_number=0 cid='0000000' passcode='ZZZZZZ' %}".replace("0000000", cid).replace("ZZZZZZ", passcode));
|
|
||||||
} else {
|
|
||||||
alert("Please enter a valid Candidate ID (CID).")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
@@ -5,7 +5,12 @@
|
|||||||
CID: {{cid}}
|
CID: {{cid}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h2>Collection: {{collection.name}}</h2>
|
<h2>Collection: {{collection.name}}
|
||||||
|
|
||||||
|
{% if collection.publish_results or cid_user_exam.completed %}
|
||||||
|
review
|
||||||
|
{% endif %}
|
||||||
|
</h2>
|
||||||
|
|
||||||
<div><p>Questions</p></div>
|
<div><p>Questions</p></div>
|
||||||
{{answer_count}} out of {{collection_length}} cases answered. Click to go to case.
|
{{answer_count}} out of {{collection_length}} cases answered. Click to go to case.
|
||||||
@@ -31,7 +36,25 @@
|
|||||||
|
|
||||||
Start time: {{cid_user_exam.start_time}}
|
Start time: {{cid_user_exam.start_time}}
|
||||||
|
|
||||||
<p>Completed: {{cid_user_exam.completed}}</p>
|
|
||||||
|
{% if collection.self_review %}
|
||||||
|
<p>Completed: <span id="completed-state">{{cid_user_exam.completed}}</span></p>
|
||||||
|
|
||||||
|
|
||||||
|
{% if not cid_user_exam.completed %}
|
||||||
|
<form hx-post=""
|
||||||
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
|
||||||
|
hx-delete
|
||||||
|
hx-confirm="Finish session?"
|
||||||
|
hx-target="#completed-state"
|
||||||
|
_="on htmx:afterOnLoad remove me"
|
||||||
|
>
|
||||||
|
<button type="submit" name="finish" value="finish">Finish</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
{% extends 'atlas/base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Start: {{collection.name}}</h2>
|
||||||
|
|
||||||
|
{% if request.user.is_authenticated and valid_user %}
|
||||||
|
User: {{request.user}}<br/>
|
||||||
|
|
||||||
|
{% if cid_exam %}
|
||||||
|
Started: {{cid_exam.start_time}} <br/>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
<a href="{% url 'atlas:collection_case_view_take_user' pk=collection.pk case_number=0 %}">
|
||||||
|
<button>Start</button>
|
||||||
|
</a>
|
||||||
|
{% else %}
|
||||||
|
Enter your CID and passcode in the below boxes.<br />
|
||||||
|
<p><input id="cid-box" type="text" value="Candidate ID"></p>
|
||||||
|
<p><input id="passcode-box" type="text" value="Passcode"></p>
|
||||||
|
|
||||||
|
<button>Start</button>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function () {
|
||||||
|
window.location.search.substr(1).split("&").forEach((item) =>
|
||||||
|
{
|
||||||
|
s = item.split("=");
|
||||||
|
if (s[0] == "cid") {
|
||||||
|
$("#cid-box").val(s[1]);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (s[0] == "passcode") {
|
||||||
|
$("#passcode-box").val(s[1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$("#cid-box, #passcode-box").keypress(function(e) {
|
||||||
|
// Enter pressed?
|
||||||
|
console.log(e)
|
||||||
|
if(e.which == 10 || e.which == 13) {
|
||||||
|
$("button").click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("button").click(() => {
|
||||||
|
let cid = $("#cid-box").val();
|
||||||
|
let passcode = $("#passcode-box").val();
|
||||||
|
|
||||||
|
if (Number.isInteger(parseInt(cid))) {
|
||||||
|
window.location.replace("{% url 'atlas:collection_case_view_take' pk=collection.pk case_number=0 cid='0000000' passcode='ZZZZZZ' %}".replace("0000000", cid).replace("ZZZZZZ", passcode));
|
||||||
|
} else {
|
||||||
|
alert("Please enter a valid Candidate ID (CID).")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
+5
-6
@@ -34,7 +34,11 @@ urlpatterns = [
|
|||||||
name="collection_update",
|
name="collection_update",
|
||||||
),
|
),
|
||||||
path("collection/<int:pk>", views.collection_detail, name="collection_detail"),
|
path("collection/<int:pk>", views.collection_detail, name="collection_detail"),
|
||||||
path("collection/<int:pk>/take", views.collection_take, name="collection_take"),
|
path(
|
||||||
|
"collection/<int:pk>/take",
|
||||||
|
views.collection_take_start,
|
||||||
|
name="collection_take_start",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"collection/<int:exam_id>/cids",
|
"collection/<int:exam_id>/cids",
|
||||||
views.GenericExamViews.exam_cids,
|
views.GenericExamViews.exam_cids,
|
||||||
@@ -95,11 +99,6 @@ urlpatterns = [
|
|||||||
views.collection_case_view_take_user,
|
views.collection_case_view_take_user,
|
||||||
name="collection_case_view_take_user",
|
name="collection_case_view_take_user",
|
||||||
),
|
),
|
||||||
path(
|
|
||||||
"collection/<int:pk>/<int:case_number>/review",
|
|
||||||
views.collection_case_view_review,
|
|
||||||
name="collection_case_view_review",
|
|
||||||
),
|
|
||||||
path(
|
path(
|
||||||
"collection/<int:pk>/json_edit",
|
"collection/<int:pk>/json_edit",
|
||||||
views.GenericExamViews.exam_json_edit,
|
views.GenericExamViews.exam_json_edit,
|
||||||
|
|||||||
+103
-33
@@ -1096,19 +1096,39 @@ def collection_detail(request, pk):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def collection_take(request, pk):
|
def collection_take_start(request, pk):
|
||||||
|
"""The starting page for taking / reviewing a case collection
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request (_type_): _description_
|
||||||
|
pk (_type_): _description_
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
_type_: _description_
|
||||||
|
"""
|
||||||
collection = get_object_or_404(CaseCollection, pk=pk)
|
collection = get_object_or_404(CaseCollection, pk=pk)
|
||||||
|
|
||||||
|
valid_user = (collection.check_logged_in_user(request),)
|
||||||
|
|
||||||
|
cid_exam = None
|
||||||
|
if valid_user:
|
||||||
|
cid_exam = collection.get_cid_user_exams(user_user=request.user).first()
|
||||||
|
|
||||||
template_variables = {
|
template_variables = {
|
||||||
"collection": collection,
|
"collection": collection,
|
||||||
"valid_user": collection.check_logged_in_user(request),
|
"valid_user": valid_user,
|
||||||
|
"cid_exam": cid_exam,
|
||||||
}
|
}
|
||||||
|
|
||||||
match collection.collection_type:
|
match collection.collection_type:
|
||||||
case "REP":
|
case "REP":
|
||||||
return render(request, "atlas/collection_take.html", template_variables)
|
return render(
|
||||||
|
request, "atlas/collection_take_start.html", template_variables
|
||||||
|
)
|
||||||
case "REV":
|
case "REV":
|
||||||
return render(request, "atlas/collection_review.html", template_variables)
|
return render(
|
||||||
|
request, "atlas/collection_review_start.html", template_variables
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@user_is_collection_author_or_atlas_editor
|
@user_is_collection_author_or_atlas_editor
|
||||||
@@ -1253,13 +1273,36 @@ def collection_take_overview_user(request, pk):
|
|||||||
def collection_take_overview(
|
def collection_take_overview(
|
||||||
request, pk: int, cid: int | None = None, passcode: str | None = None
|
request, pk: int, cid: int | None = None, passcode: str | None = None
|
||||||
):
|
):
|
||||||
|
"""
|
||||||
|
Summary page that shows which questions a user has attempted
|
||||||
|
(with / without answers)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request (_type_): _description_
|
||||||
|
pk (int): _description_
|
||||||
|
cid (int | None, optional): _description_. Defaults to None.
|
||||||
|
passcode (str | None, optional): _description_. Defaults to None.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
_type_: _description_
|
||||||
|
"""
|
||||||
collection = get_object_or_404(CaseCollection, pk=pk)
|
collection = get_object_or_404(CaseCollection, pk=pk)
|
||||||
|
|
||||||
if not collection.active and not collection.self_review:
|
collection.check_user_can_take(cid, passcode, request)
|
||||||
raise Http404("Exam not found")
|
|
||||||
|
cid_user_exam = collection.get_or_create_cid_user_exam(
|
||||||
|
cid=cid, user_user=request.user
|
||||||
|
)
|
||||||
|
|
||||||
|
if request.htmx:
|
||||||
|
if "finish" in request.POST:
|
||||||
|
cid_user_exam.completed = True
|
||||||
|
cid_user_exam.save()
|
||||||
|
|
||||||
|
return HttpResponse("True")
|
||||||
|
else:
|
||||||
|
raise Http404()
|
||||||
|
|
||||||
if not collection.check_cid_user(cid, passcode, request):
|
|
||||||
raise Http404("Error accessing exam")
|
|
||||||
|
|
||||||
cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related()
|
cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related()
|
||||||
|
|
||||||
@@ -1285,10 +1328,6 @@ def collection_take_overview(
|
|||||||
else:
|
else:
|
||||||
question_answer_tuples.append((q, None))
|
question_answer_tuples.append((q, None))
|
||||||
|
|
||||||
cid_user_exam = collection.get_or_create_cid_user_exam(
|
|
||||||
cid=cid, user_user=request.user
|
|
||||||
)
|
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"atlas/collection_take_overview.html",
|
"atlas/collection_take_overview.html",
|
||||||
@@ -1304,10 +1343,6 @@ def collection_take_overview(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def collection_case_view_review(request, pk: int, case_number: int):
|
|
||||||
return collection_case_view_take(request, pk, case_number, None, None)
|
|
||||||
|
|
||||||
|
|
||||||
def collection_case_view_take_user(request, pk: int, case_number: int):
|
def collection_case_view_take_user(request, pk: int, case_number: int):
|
||||||
return collection_case_view_take(request, pk, case_number)
|
return collection_case_view_take(request, pk, case_number)
|
||||||
|
|
||||||
@@ -1315,45 +1350,63 @@ def collection_case_view_take_user(request, pk: int, case_number: int):
|
|||||||
def collection_case_view_take(
|
def collection_case_view_take(
|
||||||
request, pk: int, case_number: int, cid=None, passcode=None
|
request, pk: int, case_number: int, cid=None, passcode=None
|
||||||
):
|
):
|
||||||
|
"""
|
||||||
|
Displays the page from which the user takes a case in the collection
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request (_type_): _description_
|
||||||
|
pk (int): _description_
|
||||||
|
case_number (int): _description_
|
||||||
|
cid (_type_, optional): _description_. Defaults to None.
|
||||||
|
passcode (_type_, optional): _description_. Defaults to None.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
Http404: If user does not have access
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
_type_: _description_
|
||||||
|
"""
|
||||||
collection = get_object_or_404(CaseCollection, pk=pk)
|
collection = get_object_or_404(CaseCollection, pk=pk)
|
||||||
|
|
||||||
form = None
|
form = None
|
||||||
answer: CidReportAnswer | UserReportAnswer
|
answer: CidReportAnswer | UserReportAnswer
|
||||||
|
|
||||||
if collection.collection_type != collection.COLLECTION_TYPE_CHOICES.REVIEW:
|
collection.check_user_can_take(cid, passcode, request)
|
||||||
if not collection.active and not collection.self_review:
|
|
||||||
raise Http404("Exam not found")
|
|
||||||
|
|
||||||
if cid is not None and not collection.check_cid_user(cid, passcode, request):
|
|
||||||
raise Http404("Error accessing exam")
|
|
||||||
|
|
||||||
cid_user_exam = collection.get_or_create_cid_user_exam(
|
|
||||||
cid=cid, 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 not collection.review_only():
|
||||||
cid_user_exam = collection.get_or_create_cid_user_exam(
|
cid_user_exam = collection.get_or_create_cid_user_exam(
|
||||||
cid=cid, user_user=request.user
|
cid=cid, user_user=request.user
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if cid_user_exam.start_time is None:
|
||||||
|
cid_user_exam.start_time = timezone.now()
|
||||||
|
cid_user_exam.save()
|
||||||
|
|
||||||
|
if collection.collection_type == "REP":
|
||||||
case_detail = CaseDetail.objects.get(case=case, collection=collection)
|
case_detail = CaseDetail.objects.get(case=case, collection=collection)
|
||||||
|
|
||||||
if cid is not None:
|
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
|
ReportAnswerForm = CidReportAnswerForm
|
||||||
else:
|
else:
|
||||||
answer = case_detail.userreportanswer_set.filter(user=request.user).first()
|
answer = case_detail.userreportanswer_set.filter(
|
||||||
|
user=request.user
|
||||||
|
).first()
|
||||||
ReportAnswerForm = UserReportAnswerForm
|
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 = ReportAnswerForm(request.POST, instance=answer)
|
form = ReportAnswerForm(request.POST, instance=answer)
|
||||||
else:
|
else:
|
||||||
form = ReportAnswerForm(request.POST)
|
form = ReportAnswerForm(request.POST)
|
||||||
|
|
||||||
|
if not cid_user_exam.completed:
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
answer = form.save(commit=False)
|
answer = form.save(commit=False)
|
||||||
answer.set_cid_or_user(cid=cid, user=request.user)
|
answer.set_cid_or_user(cid=cid, user=request.user)
|
||||||
@@ -1375,7 +1428,7 @@ def collection_case_view_take(
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
kwargs = {"pk": pk}
|
kwargs = {"pk": pk}
|
||||||
redirect_url = "atlas:collection_case_view_review"
|
redirect_url = "atlas:collection_case_view_take"
|
||||||
|
|
||||||
if "next" in request.POST:
|
if "next" in request.POST:
|
||||||
return redirect(redirect_url, case_number=case_number + 1, **kwargs)
|
return redirect(redirect_url, case_number=case_number + 1, **kwargs)
|
||||||
@@ -1399,6 +1452,8 @@ def collection_case_view_take(
|
|||||||
previous = case_number > 0
|
previous = case_number > 0
|
||||||
next = case_number < (len(cases) - 1)
|
next = case_number < (len(cases) - 1)
|
||||||
|
|
||||||
|
# Set what details a user is / is not able to view when taking the case
|
||||||
|
# this can be configured via the collection edit menu
|
||||||
if collection.publish_results:
|
if collection.publish_results:
|
||||||
show_title = collection.show_title_post
|
show_title = collection.show_title_post
|
||||||
show_history = collection.show_history_post
|
show_history = collection.show_history_post
|
||||||
@@ -1431,23 +1486,38 @@ def collection_case_view_take(
|
|||||||
"show_description": show_description,
|
"show_description": show_description,
|
||||||
"show_discussion": show_discussion,
|
"show_discussion": show_discussion,
|
||||||
"show_report": show_report,
|
"show_report": show_report,
|
||||||
|
"cid_user_exam": cid_user_exam,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@user_is_collection_author_or_atlas_editor
|
@user_is_collection_author_or_atlas_editor
|
||||||
def collection_case_view(request, pk, case_number):
|
def collection_case_view(request, pk, case_number):
|
||||||
|
"""Edit/management overview of the case (as part of the collection)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request (_type_): _description_
|
||||||
|
pk (_type_): _description_
|
||||||
|
case_number (_type_): _description_
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
Http404: _description_
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
_type_: _description_
|
||||||
|
"""
|
||||||
collection = get_object_or_404(CaseCollection, pk=pk)
|
collection = get_object_or_404(CaseCollection, pk=pk)
|
||||||
|
|
||||||
form = None
|
form = None
|
||||||
answer = None
|
answer = None
|
||||||
|
|
||||||
if collection.collection_type != collection.COLLECTION_TYPE_CHOICES.REVIEW:
|
|
||||||
if not collection.active and not collection.self_review:
|
|
||||||
raise Http404("Exam not found")
|
|
||||||
|
|
||||||
cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related()
|
cases = collection.cases.all().order_by("casedetail__sort_order").prefetch_related()
|
||||||
|
|
||||||
|
try:
|
||||||
case = cases[case_number]
|
case = cases[case_number]
|
||||||
|
except IndexError: # Catch an invalid case_number
|
||||||
|
s = f"Invalid case number: {case_number}"
|
||||||
|
raise Http404(s)
|
||||||
|
|
||||||
series_list = case.series.all().prefetch_related("images", "examination", "plane")
|
series_list = case.series.all().prefetch_related("images", "examination", "plane")
|
||||||
|
|
||||||
|
|||||||
+19
-2
@@ -503,7 +503,9 @@ class ExamCollectionGenericBase(models.Model):
|
|||||||
new.save()
|
new.save()
|
||||||
return new
|
return new
|
||||||
|
|
||||||
def get_cid_user_exams(self, cid_user=None, user_user=None):
|
def get_cid_user_exams(
|
||||||
|
self, cid_user: "CidUser" = None, user_user: User = None
|
||||||
|
) -> "CidUserExam":
|
||||||
content_type = ContentType.objects.get_for_model(self)
|
content_type = ContentType.objects.get_for_model(self)
|
||||||
if cid_user is None and user_user is None:
|
if cid_user is None and user_user is None:
|
||||||
return CidUserExam.objects.filter(
|
return CidUserExam.objects.filter(
|
||||||
@@ -1071,11 +1073,26 @@ class CidUserExam(models.Model):
|
|||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
if self.cid_user is None:
|
if self.cid_user is None:
|
||||||
|
try:
|
||||||
user = self.user_user.username
|
user = self.user_user.username
|
||||||
|
except AttributeError:
|
||||||
|
user = "None"
|
||||||
else:
|
else:
|
||||||
user = self.cid_user.cid
|
user = self.cid_user.cid
|
||||||
|
|
||||||
|
if self.start_time is None:
|
||||||
|
start_time = ""
|
||||||
|
else:
|
||||||
|
start_time = f"{ self.start_time:%Y-%m-%d %H:%M }"
|
||||||
|
|
||||||
|
if self.end_time is None:
|
||||||
|
end_time = ""
|
||||||
|
else:
|
||||||
|
end_time = f"{ self.end_time:%Y-%m-%d %H:%M }"
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
f"{user}: {self.start_time:%Y-%m-%d %H:%M} {self.end_time:%Y-%m-%d %H:%M}"
|
f"{user}: {start_time} {end_time}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user