Refactor CaseDetail references to Casedetail across templates and views

- Updated all instances of 'case_detail' to 'casedetail' in templates to maintain consistency.
- Adjusted view functions to use 'casedetail' instead of 'case_detail' for better clarity.
- Renamed the field 'case_detail' to 'casedetail' in the CasePrior model to align with the new naming convention.
- Ensured that all related logic and references in forms and data handling reflect this change.
This commit is contained in:
Ross
2025-11-17 10:34:27 +00:00
parent 7f4570417e
commit 12b7fa6629
19 changed files with 230 additions and 208 deletions
+5 -22
View File
@@ -831,7 +831,7 @@ class BaseReportAnswerForm(ModelForm):
# "answer": "Write your answer in here." # "answer": "Write your answer in here."
# } # }
def __init__(self, *args, case_detail, **kwargs): def __init__(self, *args, casedetail, **kwargs):
super(BaseReportAnswerForm, self).__init__(*args, **kwargs) super(BaseReportAnswerForm, self).__init__(*args, **kwargs)
self.fields["answer"].required = False self.fields["answer"].required = False
@@ -847,12 +847,12 @@ class BaseQuestionAnswerForm(ModelForm):
# "answer": "Write your answer in here." # "answer": "Write your answer in here."
# } # }
def __init__(self, *args, case_detail, **kwargs): def __init__(self, *args, casedetail, **kwargs):
super(BaseQuestionAnswerForm, self).__init__(*args, **kwargs) super(BaseQuestionAnswerForm, self).__init__(*args, **kwargs)
# self.fields["json_answer"].schema = case_detail.question_schema # self.fields["json_answer"].schema = casedetail.question_schema
if case_detail.question_schema is not None: if casedetail.question_schema is not None:
self.fields["json_answer"] = JSONSchemaField( self.fields["json_answer"] = JSONSchemaField(
schema=case_detail.question_schema, options="schema/options.json" schema=casedetail.question_schema, options="schema/options.json"
) )
self.fields["json_answer"].label = "" self.fields["json_answer"].label = ""
@@ -1153,23 +1153,6 @@ class PriorCaseForm(Form):
prior_visibility = CharField(max_length=2, required=True) prior_visibility = CharField(max_length=2, required=True)
# def __init__(self, *args, **kwargs):
# self.case_detail = kwargs.pop(
# "case_detail"
# ) # To get request.user. Do not use kwargs.pop('user', None) due to potential security hole
# super(PriorCaseForm, self).__init__(*args, **kwargs)
# prior_cases = self.case_detail.case.get_all_prior_cases()
# if not prior_cases:
# prior_cases = Case.objects.none()
# self.fields["case"] = ChoiceField(
# required=False,
# # widget=Select(verbose_name="Series", is_stacked=False),
# )
class CaseSeriesForm(forms.ModelForm): class CaseSeriesForm(forms.ModelForm):
def __init__(self, *args, queryset, user=None, is_atlas_editor=False, **kwargs): def __init__(self, *args, queryset, user=None, is_atlas_editor=False, **kwargs):
@@ -0,0 +1,22 @@
# Generated by Django 5.2.7 on 2025-11-17 10:28
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('atlas', '0084_resource_open_access'),
]
operations = [
migrations.RenameField(
model_name='caseprior',
old_name='case_detail',
new_name='casedetail',
),
migrations.AlterUniqueTogether(
name='caseprior',
unique_together={('casedetail', 'prior_case')},
),
]
+3 -3
View File
@@ -1545,7 +1545,7 @@ class CaseDetail(models.Model):
return mark_safe(html) return mark_safe(html)
class CasePrior(models.Model): class CasePrior(models.Model):
case_detail = models.ForeignKey(CaseDetail, on_delete=models.CASCADE) casedetail = models.ForeignKey(CaseDetail, on_delete=models.CASCADE)
prior_case = models.ForeignKey(Case, on_delete=models.CASCADE, related_name="prior_case") prior_case = models.ForeignKey(Case, on_delete=models.CASCADE, related_name="prior_case")
relation_text = models.CharField(max_length=255, blank=True, help_text="Text to describe the relationship between the cases") relation_text = models.CharField(max_length=255, blank=True, help_text="Text to describe the relationship between the cases")
@@ -1564,10 +1564,10 @@ class CasePrior(models.Model):
) )
class Meta: class Meta:
unique_together = ("case_detail", "prior_case") unique_together = ("casedetail", "prior_case")
def __str__(self) -> str: def __str__(self) -> str:
return f"{self.case_detail.case} -> {self.prior_case}" return f"{self.casedetail.case} -> {self.prior_case}"
class BaseReportAnswer(models.Model): class BaseReportAnswer(models.Model):
question = models.ForeignKey(CaseDetail, on_delete=models.CASCADE) question = models.ForeignKey(CaseDetail, on_delete=models.CASCADE)
@@ -464,7 +464,7 @@
{% if casedetail %} {% if casedetail %}
{% include 'atlas/partials/collection_question_block.html' with case_detail=casedetail can_edit=can_edit %} {% include 'atlas/partials/collection_question_block.html' with can_edit=can_edit %}
{% endif %} {% endif %}
@@ -3,9 +3,9 @@
{% block content %} {% block content %}
{% include 'atlas/partials/_viewing_case_as_part_of_collection.html' %} {% include 'atlas/partials/_viewing_case_as_part_of_collection.html' with nav_link_view="atlas:collection_case_details" %}
<h2>Case: <a href="{% url 'atlas:case_detail' case_detail.case.pk %}">{{case_detail.case.title}}</a></h2> <h2>Case: <a href="{% url 'atlas:case_detail' casedetail.case.pk %}">{{casedetail.case.title}}</a></h2>
<p>This page allows you to configure how the case is displayed as part of the collection.</p> <p>This page allows you to configure how the case is displayed as part of the collection.</p>
@@ -3,13 +3,14 @@
{% block content %} {% block content %}
{% include 'atlas/partials/_viewing_case_as_part_of_collection.html' with nav_link_view="atlas:collection_case_displaysetup" %}
<h2>Setup default display for case</h2> <h2>Setup default display for case</h2>
<div id="root" class="dicom-viewer-root" data-images="{{case_detail.case.get_series_images_nested}}" <div id="root" class="dicom-viewer-root" data-images="{{casedetail.case.get_series_images_nested}}"
style="box-sizing: border-box; background: #222; width: 100vw; height: 800px; max-width: 1600px;" style="box-sizing: border-box; background: #222; width: 100vw; height: 800px; max-width: 1600px;"
data-auto-cache-stack="true" data-auto-cache-stack="true"
{% if case_detail.default_viewerstate %} {% if casedetail.default_viewerstate %}
data-viewerstate={{ case_detail.default_viewerstate }} data-viewerstate={{ casedetail.default_viewerstate }}
{% endif %} {% endif %}
></div> ></div>
@@ -29,7 +30,7 @@ document.getElementById('save-viewerstate').addEventListener('click', function()
document.getElementById('viewerstate-save-response').innerHTML = "<span class='text-danger'>Viewer state could not be retrieved.</span>"; document.getElementById('viewerstate-save-response').innerHTML = "<span class='text-danger'>Viewer state could not be retrieved.</span>";
return; return;
} }
fetch("{% url 'atlas:collection_case_displaysetup' case_detail.collection.pk case_detail.case.pk %}", { fetch("{% url 'atlas:collection_case_displaysetup' casedetail.collection.pk casedetail.case.pk %}", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@@ -46,7 +47,7 @@ document.getElementById('save-viewerstate').addEventListener('click', function()
}); });
}); });
document.getElementById('reset-viewerstate').addEventListener('click', function() { document.getElementById('reset-viewerstate').addEventListener('click', function() {
fetch("{% url 'atlas:collection_case_displaysetup' case_detail.collection.pk case_detail.case.pk %}", { fetch("{% url 'atlas:collection_case_displaysetup' casedetail.collection.pk casedetail.case.pk %}", {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@@ -4,9 +4,9 @@
{% block content %} {% block content %}
{% include 'atlas/partials/_viewing_case_as_part_of_collection.html' with casedetail=case_detail %} {% include 'atlas/partials/_viewing_case_as_part_of_collection.html' with nav_link_view="atlas:collection_case_priors" %}
<h2 class="mb-3">Case: <a href="{% url 'atlas:case_detail' case_detail.case.pk %}" class="text-decoration-none">{{case_detail.case.title}}</a></h2> <h2 class="mb-3">Managing Priors for Case: <a href="{% url 'atlas:case_detail' casedetail.case.pk %}" class="text-decoration-none">{{casedetail.case.title}}</a></h2>
<div class="card mb-4"> <div class="card mb-4">
<div class="card-body"> <div class="card-body">
@@ -19,7 +19,7 @@
<div class="row g-3"> <div class="row g-3">
{% for case, added, relation, visibility in available_priors %} {% for case, added, relation, visibility in available_priors %}
{% include 'atlas/partials/_prior_card.html' with case=case added=added relation=relation visibility=visibility case_detail=case_detail collection=collection %} {% include 'atlas/partials/_prior_card.html' with case=case added=added relation=relation visibility=visibility collection=collection %}
{% empty %} {% empty %}
<div class="col-12"> <div class="col-12">
<div class="alert alert-info">No available prior cases found for the case.</div> <div class="alert alert-info">No available prior cases found for the case.</div>
@@ -4,11 +4,11 @@
{% block content %} {% block content %}
{% include 'atlas/partials/_viewing_case_as_part_of_collection.html' with casedetail=case_detail %} {% include 'atlas/partials/_viewing_case_as_part_of_collection.html' with nav_link_view="atlas:collection_case_questions" %}
<h2>Case: <a href="{% url 'atlas:case_detail' case_detail.case.pk %}">{{case_detail.case.title}}</a></h2> <h2>Case: <a href="{% url 'atlas:case_detail' casedetail.case.pk %}">{{casedetail.case.title}}</a></h2>
{% if case_detail.question_schema is not None and not case_detail.question_answers %} {% if casedetail.question_schema is not None and not casedetail.question_answers %}
<div class="alert alert-danger" role="alert"> <div class="alert alert-danger" role="alert">
@@ -32,7 +32,7 @@
Import schema from: Import schema from:
<button class="btn btn-primary btn-sm" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight" aria-controls="offcanvasRight" <button class="btn btn-primary btn-sm" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight" aria-controls="offcanvasRight"
hx-get="{% url 'atlas:collection_question_schemas' case_detail.collection.id %}" hx-get="{% url 'atlas:collection_question_schemas' casedetail.collection.id %}"
hx-target=".offcanvas-body" hx-target=".offcanvas-body"
>Collection questions</button> >Collection questions</button>
<button class="btn btn-primary btn-sm" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight" aria-controls="offcanvasRight" <button class="btn btn-primary btn-sm" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasRight" aria-controls="offcanvasRight"
@@ -44,7 +44,7 @@
Question Block Title Question Block Title
</summary> </summary>
<p>Title of the question block.</p> <p>Title of the question block.</p>
<input id="question_block_title_input" type="text" name="title" value="{{case_detail.question_schema.title}}" class="form-control" placeholder="Question title" aria-label="Question title"> <input id="question_block_title_input" type="text" name="title" value="{{casedetail.question_schema.title}}" class="form-control" placeholder="Question title" aria-label="Question title">
</details> </details>
<details><summary>Modify Questions</summary> <details><summary>Modify Questions</summary>
<div id="questions-container" style="margin-top: 20px;"> <div id="questions-container" style="margin-top: 20px;">
@@ -113,7 +113,7 @@
</form> {% endcomment %} </form> {% endcomment %}
{% if case_detail.question_schema %} {% if casedetail.question_schema %}
<h2>Question display</h2> <h2>Question display</h2>
This shows the form as it will be displayed (with the correct answers). If you wish to edit a correct answer you can change it below. This shows the form as it will be displayed (with the correct answers). If you wish to edit a correct answer you can change it below.
@@ -57,7 +57,7 @@
{% endif %} {% endif %}
{% if show_history %} {% if show_history %}
<div> <div>
History: {{case_detail.get_history_pre|linebreaks}} History: {{casedetail.get_history_pre|linebreaks}}
</div> </div>
{% endif %} {% endif %}
@@ -92,7 +92,7 @@
<div id="main_viewer" class="dicom-viewer-root" <div id="main_viewer" class="dicom-viewer-root"
style="box-sizing: border-box; background: #222; width: 100%; height: 600px;" style="box-sizing: border-box; background: #222; width: 100%; height: 600px;"
data-auto-cache-stack="false" data-auto-cache-stack="false"
data-named-stacks='{{case_detail.get_case_named_stacks}}' data-named-stacks='{{casedetail.get_case_named_stacks}}'
></div> ></div>
</details> </details>
@@ -2,9 +2,9 @@
{% block content %} {% block content %}
<div class="vstack gap-3"> <div class="vstack gap-3">
{% for case_detail, answers in case_map.items %} {% for casedetail, answers in case_map.items %}
<div class="border border-dark"> <div class="border border-dark">
<h4>Case: {{case_detail.case.title}}</h4> <h4>Case: {{casedetail.case.title}}</h4>
Answers Answers
<ul> <ul>
{% for answer in answers %} {% for answer in answers %}
+15 -15
View File
@@ -32,7 +32,7 @@
<button class="open-case-local no-padding" data-target=case.pk data-type="case">Load</button> <button class="open-case-local no-padding" data-target=case.pk data-type="case">Load</button>
<!-- Edit mode link for case --> <!-- Edit mode link for case -->
<button class="view-link-case btn btn-outline-primary btn-sm ms-2" style="display:none;"> <button class="view-link-case btn btn-outline-primary btn-sm ms-2" style="display:none;">
<a href="{% url 'atlas:case_detail' case.pk %}" style="color: inherit; text-decoration: none;">View Case</a> <a href="{% url 'atlas:casedetail' case.pk %}" style="color: inherit; text-decoration: none;">View Case</a>
</button> </button>
<button class="edit-link-case btn btn-outline-warning btn-sm ms-2" style="display:none;"> <button class="edit-link-case btn btn-outline-warning btn-sm ms-2" style="display:none;">
<a href="{% url 'atlas:case_update' case.pk %}" style="color: inherit; text-decoration: none;">Edit Case</a> <a href="{% url 'atlas:case_update' case.pk %}" style="color: inherit; text-decoration: none;">Edit Case</a>
@@ -69,7 +69,7 @@
</div> </div>
{# Hidden per-case question snippet to inject when case is loaded #} {# Hidden per-case question snippet to inject when case is loaded #}
<div class="question-block-snippet" style="display:none;"> <div class="question-block-snippet" style="display:none;">
{% include 'atlas/partials/collection_question_block.html' with case_detail=casedetail %} {% include 'atlas/partials/collection_question_block.html' with casedetail=casedetail %}
</div> </div>
{% if case.display_sets.all %} {% if case.display_sets.all %}
<details class="displayset-detail"><summary>Display Sets:</summary> <details class="displayset-detail"><summary>Display Sets:</summary>
@@ -212,14 +212,14 @@
let c = this.closest(".case-item"); let c = this.closest(".case-item");
console.log('clicked local', c) console.log('clicked local', c)
console.log('open local', c.dataset.case) console.log('open local', c.dataset.case)
case_details = JSON.parse(c.dataset.casejson); casedetails = JSON.parse(c.dataset.casejson);
let viewerstate = JSON.parse(c.dataset.viewerstate) || {}; let viewerstate = JSON.parse(c.dataset.viewerstate) || {};
$('#loading-case').show() $('#loading-case').show()
$("#open-viewer-local").addClass("flash-button"); $("#open-viewer-local").addClass("flash-button");
$('#current-case-title').html("<span class='title'>Case:</span> "+c.dataset.title); $('#current-case-title').html("<span class='title'>Case:</span> "+c.dataset.title);
$("#current-case-history").html("<span class='title'>History:</span> "+case_details['history']); $("#current-case-history").html("<span class='title'>History:</span> "+casedetails['history']);
$("#current-case-discussion").html("<span class='title'>Discussion:</span> "+case_details['discussion']); $("#current-case-discussion").html("<span class='title'>Discussion:</span> "+casedetails['discussion']);
$("#current-case-report").html("<span class='title'>Report:</span> "+case_details['report']); $("#current-case-report").html("<span class='title'>Report:</span> "+casedetails['report']);
bc.postMessage({"type": "open", bc.postMessage({"type": "open",
"case" : c.dataset.case, "images": c.dataset.images, "case" : c.dataset.case, "images": c.dataset.images,
@@ -239,15 +239,15 @@
let c = this; let c = this;
console.log('clicked local', c) console.log('clicked local', c)
console.log('open local', c.dataset.case) console.log('open local', c.dataset.case)
case_details = JSON.parse(c.dataset.casejson); casedetails = JSON.parse(c.dataset.casejson);
let viewerstate = JSON.parse(c.dataset.viewerstate) || {}; let viewerstate = JSON.parse(c.dataset.viewerstate) || {};
let annotations = JSON.parse(c.dataset.annotations) || {}; let annotations = JSON.parse(c.dataset.annotations) || {};
$('#loading-case').show() $('#loading-case').show()
$("#open-viewer-local").addClass("flash-button"); $("#open-viewer-local").addClass("flash-button");
$('#current-case-title').html("<span class='title'>Case:</span> "+c.dataset.title); $('#current-case-title').html("<span class='title'>Case:</span> "+c.dataset.title);
$("#current-case-history").html("<span class='title'>History:</span> "+case_details['history']); $("#current-case-history").html("<span class='title'>History:</span> "+casedetails['history']);
$("#current-case-discussion").html("<span class='title'>Discussion:</span> "+case_details['discussion']); $("#current-case-discussion").html("<span class='title'>Discussion:</span> "+casedetails['discussion']);
$("#current-case-report").html("<span class='title'>Report:</span> "+case_details['report']); $("#current-case-report").html("<span class='title'>Report:</span> "+casedetails['report']);
bc.postMessage({"type": "open", bc.postMessage({"type": "open",
"case" : c.dataset.case, "images": c.dataset.images, "case" : c.dataset.case, "images": c.dataset.images,
@@ -302,15 +302,15 @@
let c = $(this).closest(".case-item"); let c = $(this).closest(".case-item");
case_details = c.data('casejson'); casedetails = c.data('casejson');
console.log(case_details); console.log(casedetails);
$('#loading-case').show() $('#loading-case').show()
$("#open-viewer").addClass("flash-button"); $("#open-viewer").addClass("flash-button");
$('#current-case-title').html("<span class='title'>Case:</span> "+c.data('title')); $('#current-case-title').html("<span class='title'>Case:</span> "+c.data('title'));
$("#current-case-history").html("<span class='title'>History:</span> "+case_details['history']); $("#current-case-history").html("<span class='title'>History:</span> "+casedetails['history']);
$("#current-case-discussion").html("<span class='title'>Discussion:</span> "+case_details['discussion']); $("#current-case-discussion").html("<span class='title'>Discussion:</span> "+casedetails['discussion']);
$("#current-case-report").html("<span class='title'>Report:</span> "+case_details['report']); $("#current-case-report").html("<span class='title'>Report:</span> "+casedetails['report']);
console.log($(this).data('type')) console.log($(this).data('type'))
if ($(this).data('type') == 'case') { if ($(this).data('type') == 'case') {
+1 -1
View File
@@ -26,7 +26,7 @@
{% if page_obj.object_list %} {% if page_obj.object_list %}
<div class="list-group"> <div class="list-group">
{% for normal in page_obj.object_list %} {% for normal in page_obj.object_list %}
<a class="list-group-item list-group-item-action" href="{% url 'atlas:case_detail' normal.case.pk %}"> <a class="list-group-item list-group-item-action" href="{% url 'atlas:casedetail' normal.case.pk %}">
<div class="d-flex w-100 justify-content-between"> <div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{ normal.case.title }}</h5> <h5 class="mb-1">{{ normal.case.title }}</h5>
<small class="text-muted">{{ normal.added_date|date:"Y-m-d" }}</small> <small class="text-muted">{{ normal.added_date|date:"Y-m-d" }}</small>
@@ -25,7 +25,7 @@
</div> </div>
{% if not added %} {% if not added %}
<form class="row g-2" hx-post="{% url 'atlas:collection_case_priors' collection.id case_detail.case.pk %}" <form class="row g-2" hx-post="{% url 'atlas:collection_case_priors' collection.id casedetail.case.pk %}"
hx-target="#prior-card-{{case.id}}" hx-swap="outerHTML"> hx-target="#prior-card-{{case.id}}" hx-swap="outerHTML">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="prior_case_id" value="{{case.id}}" /> <input type="hidden" name="prior_case_id" value="{{case.id}}" />
@@ -44,7 +44,7 @@
</div> </div>
</form> </form>
{% else %} {% else %}
<form hx-post="{% url 'atlas:collection_case_priors' collection.id case_detail.case.pk %}" <form hx-post="{% url 'atlas:collection_case_priors' collection.id casedetail.case.pk %}"
hx-target="#prior-card-{{case.id}}" hx-swap="outerHTML"> hx-target="#prior-card-{{case.id}}" hx-swap="outerHTML">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="remove" value="{{case.id}}" /> <input type="hidden" name="remove" value="{{case.id}}" />
@@ -1,10 +1,10 @@
{# Partial: render questions and answers as HTML. #} {# Partial: render questions and answers as HTML. #}
{% if case_detail.question_schema %} {% if casedetail.question_schema %}
<div class="collection-question-block"> <div class="collection-question-block">
<h4>Questions</h4> <h4>Questions</h4>
<dl class="row"> <dl class="row">
{% for name, prop in case_detail.question_schema.properties.items %} {% for name, prop in casedetail.question_schema.properties.items %}
<dt class="col-sm-4">{{ prop.title|default:name }}</dt> <dt class="col-sm-4">{{ prop.title|default:name }}</dt>
<dd class="col-sm-8"> <dd class="col-sm-8">
{% if prop.description %} {% if prop.description %}
@@ -18,8 +18,8 @@
{% endif %} {% endif %}
{# Safely fetch the stored/example answer using the project's `get_item` filter. #} {# Safely fetch the stored/example answer using the project's `get_item` filter. #}
{% if case_detail.question_answers %} {% if casedetail.question_answers %}
{% with correct=case_detail.question_answers|get_item:name %} {% with correct=casedetail.question_answers|get_item:name %}
<div class="mt-2"> <div class="mt-2">
<strong>Example / Correct:</strong> <strong>Example / Correct:</strong>
{% if correct %} {% if correct %}
@@ -37,7 +37,7 @@
{% if user_answer %} {% if user_answer %}
{% if user_answer|get_item:name %} {% if user_answer|get_item:name %}
{% with ua=user_answer|get_item:name %} {% with ua=user_answer|get_item:name %}
{% with correct=case_detail.question_answers|get_item:name %} {% with correct=casedetail.question_answers|get_item:name %}
<div class="mt-1"> <div class="mt-1">
<strong>Your answer:</strong> <strong>Your answer:</strong>
<span class="ms-2 {% if ua == correct %}text-success{% else %}text-danger{% endif %}">{{ ua }}</span> <span class="ms-2 {% if ua == correct %}text-success{% else %}text-danger{% endif %}">{{ ua }}</span>
@@ -2,7 +2,7 @@
<ul class="list-group list-group-flush"> <ul class="list-group list-group-flush">
{% for case in series.case.all %} {% for case in series.case.all %}
<li id="case-link-{{ case.pk }}" class="list-group-item d-flex justify-content-between align-items-center case-item"> <li id="case-link-{{ case.pk }}" class="list-group-item d-flex justify-content-between align-items-center case-item">
<a href="{% url 'atlas:case_detail' pk=case.pk %}">{{case}}</a> <a href="{% url 'atlas:casedetail' pk=case.pk %}">{{case}}</a>
{% if can_edit %} {% if can_edit %}
<button hx-post="{% url 'atlas:remove_series_from_case' series.pk case.pk %}" <button hx-post="{% url 'atlas:remove_series_from_case' series.pk case.pk %}"
hx-target="#cases-list" hx-target="#cases-list"
+125 -109
View File
@@ -2757,8 +2757,8 @@ def collection_take_start(request, pk, cid=None, passcode=None):
@user_is_collection_author_or_atlas_editor @user_is_collection_author_or_atlas_editor
def collection_case_priors(request, exam_id, case_id): def collection_case_priors(request, exam_id, case_id):
case_detail = CaseDetail.objects.get(case=case_id, collection=exam_id) casedetail = CaseDetail.objects.get(case=case_id, collection=exam_id)
collection = case_detail.collection collection = casedetail.collection
if request.htmx: if request.htmx:
# Ensure we can render the updated single-card partial and return it so HTMX # Ensure we can render the updated single-card partial and return it so HTMX
@@ -2767,7 +2767,7 @@ def collection_case_priors(request, exam_id, case_id):
if "remove" in request.POST: if "remove" in request.POST:
prior_pk = request.POST["remove"] prior_pk = request.POST["remove"]
try: try:
p = CasePrior.objects.get(case_detail=case_detail, prior_case=prior_pk) p = CasePrior.objects.get(casedetail=casedetail, prior_case=prior_pk)
p.delete() p.delete()
except CasePrior.DoesNotExist: except CasePrior.DoesNotExist:
# Already removed; continue and render the not-added card # Already removed; continue and render the not-added card
@@ -2785,7 +2785,7 @@ def collection_case_priors(request, exam_id, case_id):
"added": added, "added": added,
"relation": relation, "relation": relation,
"visibility": visibility, "visibility": visibility,
"case_detail": case_detail, "casedetail": casedetail,
"collection": collection, "collection": collection,
}, },
request=request, request=request,
@@ -2807,7 +2807,7 @@ def collection_case_priors(request, exam_id, case_id):
"added": added, "added": added,
"relation": relation, "relation": relation,
"visibility": visibility, "visibility": visibility,
"case_detail": case_detail, "casedetail": casedetail,
"collection": collection, "collection": collection,
"error": "You need to enter text to describe the relationship between the cases", "error": "You need to enter text to describe the relationship between the cases",
}, },
@@ -2816,7 +2816,7 @@ def collection_case_priors(request, exam_id, case_id):
return HttpResponse(html) return HttpResponse(html)
prior_case = Case.objects.get(pk=request.POST["prior_case_id"]) prior_case = Case.objects.get(pk=request.POST["prior_case_id"])
p, created = CasePrior.objects.get_or_create( p, created = CasePrior.objects.get_or_create(
case_detail=case_detail, prior_case=prior_case casedetail=casedetail, prior_case=prior_case
) )
p.relation_text = request.POST.get("relation", "") p.relation_text = request.POST.get("relation", "")
p.prior_visibility = request.POST.get("prior_visibility", "AL") p.prior_visibility = request.POST.get("prior_visibility", "AL")
@@ -2833,7 +2833,7 @@ def collection_case_priors(request, exam_id, case_id):
"added": added, "added": added,
"relation": relation, "relation": relation,
"visibility": visibility, "visibility": visibility,
"case_detail": case_detail, "casedetail": casedetail,
"collection": collection, "collection": collection,
}, },
request=request, request=request,
@@ -2842,15 +2842,15 @@ def collection_case_priors(request, exam_id, case_id):
else: else:
return HttpResponse("False", status=400) return HttpResponse("False", status=400)
collection = case_detail.collection collection = casedetail.collection
added_priors = CasePrior.objects.filter(case_detail=case_detail) added_priors = CasePrior.objects.filter(casedetail=casedetail)
added_relation_map = {} added_relation_map = {}
for prior in added_priors: for prior in added_priors:
added_relation_map[prior.prior_case] = (prior.relation_text, prior.prior_visibility) added_relation_map[prior.prior_case] = (prior.relation_text, prior.prior_visibility)
case = case_detail.case case = casedetail.case
available_cases = case.get_all_prior_cases() available_cases = case.get_all_prior_cases()
@@ -2864,22 +2864,22 @@ def collection_case_priors(request, exam_id, case_id):
form = PriorCaseForm() form = PriorCaseForm()
case_number, case_count = collection.get_index_of_case( case_number, case_count = collection.get_index_of_case(
case_detail.case, case_count=True casedetail.case, case_count=True
) )
previous = collection.get_previous_case(case_detail.case) previous = collection.get_previous_case(casedetail.case)
next = collection.get_next_case(case_detail.case) next = collection.get_next_case(casedetail.case)
return render( return render(
request, request,
"atlas/collection_case_priors.html", "atlas/collection_case_priors.html",
{ {
"case_detail": case_detail, "casedetail": casedetail,
"form": form, "form": form,
#"model_form": model_form, #"model_form": model_form,
# "example_form": example_form, # "example_form": example_form,
"collection": collection, "collection": collection,
"case": case_detail.case, "case": casedetail.case,
"previous": previous, "previous": previous,
"next": next, "next": next,
"collection_length": case_count, "collection_length": case_count,
@@ -2892,9 +2892,9 @@ def collection_case_priors(request, exam_id, case_id):
@user_is_collection_author_or_atlas_editor @user_is_collection_author_or_atlas_editor
def collection_case_questions(request, exam_id, case_id): def collection_case_questions(request, exam_id, case_id):
case_detail = CaseDetail.objects.get(case=case_id, collection=exam_id) casedetail = CaseDetail.objects.get(case=case_id, collection=exam_id)
collection = case_detail.collection collection = casedetail.collection
if not collection.collection_type == "QUE": if not collection.collection_type == "QUE":
raise Http404("Collection not in question mode") raise Http404("Collection not in question mode")
@@ -2903,29 +2903,29 @@ def collection_case_questions(request, exam_id, case_id):
# Called if the user saves the correct answer form # Called if the user saves the correct answer form
if request.POST.get("submit") == "answer": if request.POST.get("submit") == "answer":
# answers = request.POST # answers = request.POST
case_detail.question_answers = json.loads(request.POST.get("json_answer")) casedetail.question_answers = json.loads(request.POST.get("json_answer"))
case_detail.save() casedetail.save()
example_form = JsonAnswerForm( example_form = JsonAnswerForm(
request.POST, question_schema=case_detail.question_schema request.POST, question_schema=casedetail.question_schema
) )
form = CaseQuestionForm(instance=case_detail) form = CaseQuestionForm(instance=casedetail)
# Called if the user saves the main form # Called if the user saves the main form
elif request.POST.get("submit") == "save": elif request.POST.get("submit") == "save":
form = CaseQuestionForm(request.POST, instance=case_detail) form = CaseQuestionForm(request.POST, instance=casedetail)
if form.is_valid(): if form.is_valid():
form.save() form.save()
# Add any additional logic or redirection here # Add any additional logic or redirection here
# example_form = JsonAnswerForm(request.POST, question_schema=case_detail.question_schema) # example_form = JsonAnswerForm(request.POST, question_schema=casedetail.question_schema)
post_data = request.POST.copy() post_data = request.POST.copy()
if ( if (
case_detail.question_schema is not None casedetail.question_schema is not None
and case_detail.question_answers is not None and casedetail.question_answers is not None
): ):
question_keys = set(case_detail.question_schema["properties"].keys()) question_keys = set(casedetail.question_schema["properties"].keys())
answer_keys = set(case_detail.question_answers.keys()) answer_keys = set(casedetail.question_answers.keys())
answers = {} answers = {}
for key, value in case_detail.question_answers.items(): for key, value in casedetail.question_answers.items():
if key in question_keys: if key in question_keys:
answers[key] = value answers[key] = value
@@ -2935,35 +2935,35 @@ def collection_case_questions(request, exam_id, case_id):
answers[key] = "" answers[key] = ""
post_data["json_answer"] = json.dumps(answers) post_data["json_answer"] = json.dumps(answers)
case_detail.question_answers = answers casedetail.question_answers = answers
case_detail.save() casedetail.save()
example_form = JsonAnswerForm( example_form = JsonAnswerForm(
post_data, question_schema=case_detail.question_schema post_data, question_schema=casedetail.question_schema
) )
form = CaseQuestionForm(instance=case_detail) form = CaseQuestionForm(instance=casedetail)
# This shouldn't happen # This shouldn't happen
else: else:
assert False assert False
form = CaseQuestionForm(request.POST, instance=case_detail) form = CaseQuestionForm(request.POST, instance=casedetail)
else: else:
post_data = request.POST.copy() post_data = request.POST.copy()
post_data["json_answer"] = json.dumps(case_detail.question_answers) post_data["json_answer"] = json.dumps(casedetail.question_answers)
example_form = JsonAnswerForm( example_form = JsonAnswerForm(
post_data, question_schema=case_detail.question_schema post_data, question_schema=casedetail.question_schema
) )
form = CaseQuestionForm(instance=case_detail) form = CaseQuestionForm(instance=casedetail)
pass pass
# post_data = None # post_data = None
# if case_detail.question_schema is not None and case_detail.question_answers is not None: # if casedetail.question_schema is not None and casedetail.question_answers is not None:
# question_keys = set(case_detail.question_schema["properties"].keys()) # question_keys = set(casedetail.question_schema["properties"].keys())
# answer_keys = set(case_detail.question_answers.keys()) # answer_keys = set(casedetail.question_answers.keys())
# answers = {} # answers = {}
# for key, value in case_detail.question_answers.items(): # for key, value in casedetail.question_answers.items():
# if key in question_keys: # if key in question_keys:
# answers[key] = value # answers[key] = value
@@ -2974,28 +2974,28 @@ def collection_case_questions(request, exam_id, case_id):
# post_data = request.POST.copy() # post_data = request.POST.copy()
# post_data["json_answer"]= json.dumps(answers) # post_data["json_answer"]= json.dumps(answers)
# case_detail.question_answers = answers # casedetail.question_answers = answers
# example_form = JsonAnswerForm(post_data, question_schema=case_detail.question_schema) # example_form = JsonAnswerForm(post_data, question_schema=casedetail.question_schema)
# form = CaseQuestionForm(instance=case_detail) # form = CaseQuestionForm(instance=casedetail)
# blank_form = JsonAnswerForm(question_schema=case_detail.question_schema) # blank_form = JsonAnswerForm(question_schema=casedetail.question_schema)
case_number, case_count = collection.get_index_of_case( case_number, case_count = collection.get_index_of_case(
case_detail.case, case_count=True casedetail.case, case_count=True
) )
previous = collection.get_previous_case(case_detail.case) previous = collection.get_previous_case(casedetail.case)
next = collection.get_next_case(case_detail.case) next = collection.get_next_case(casedetail.case)
return render( return render(
request, request,
"atlas/collection_case_questions.html", "atlas/collection_case_questions.html",
{ {
"case_detail": case_detail, "casedetail": casedetail,
"form": form, "form": form,
"example_form": example_form, "example_form": example_form,
"collection": collection, "collection": collection,
"case": case_detail.case, "case": casedetail.case,
"previous": previous, "previous": previous,
"next": next, "next": next,
"collection_length": case_count, "collection_length": case_count,
@@ -3005,12 +3005,12 @@ def collection_case_questions(request, exam_id, case_id):
@user_is_collection_author_or_atlas_editor @user_is_collection_author_or_atlas_editor
def collection_case_details(request, exam_id, case_id): def collection_case_details(request, exam_id, case_id):
case_detail = CaseDetail.objects.get(case=case_id, collection=exam_id) casedetail = CaseDetail.objects.get(case=case_id, collection=exam_id)
collection = case_detail.collection collection = casedetail.collection
if request.method == "POST": if request.method == "POST":
form = CaseDetailForm(request.POST, instance=case_detail) form = CaseDetailForm(request.POST, instance=casedetail)
if form.is_valid(): if form.is_valid():
form.save() form.save()
if request.htmx: if request.htmx:
@@ -3020,23 +3020,23 @@ def collection_case_details(request, exam_id, case_id):
if request.htmx: if request.htmx:
return HttpResponse("Invalid form", status=400) return HttpResponse("Invalid form", status=400)
else: else:
form = CaseDetailForm(instance=case_detail) form = CaseDetailForm(instance=casedetail)
case_number, case_count = collection.get_index_of_case( case_number, case_count = collection.get_index_of_case(
case_detail.case, case_count=True casedetail.case, case_count=True
) )
previous = collection.get_previous_case(case_detail.case) previous = collection.get_previous_case(casedetail.case)
next = collection.get_next_case(case_detail.case) next = collection.get_next_case(casedetail.case)
return render( return render(
request, request,
"atlas/collection_case_details.html", "atlas/collection_case_details.html",
{ {
"case_detail": case_detail, "casedetail": casedetail,
"form": form, "form": form,
"collection": collection, "collection": collection,
"case": case_detail.case, "case": casedetail.case,
"previous": previous, "previous": previous,
"next": next, "next": next,
"collection_length": case_count, "collection_length": case_count,
@@ -3054,14 +3054,14 @@ def collection_mark_overview(request, pk):
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( casedetails = CaseDetail.objects.filter(
case__in=cases, collection=collection case__in=cases, collection=collection
).prefetch_related("case") ).prefetch_related("case")
answers = CidReportAnswer.objects.filter(question__in=case_details) answers = CidReportAnswer.objects.filter(question__in=casedetails)
case_map = {} case_map = {}
for cd in case_details: for cd in casedetails:
case_map[cd] = [] case_map[cd] = []
for answer in answers: for answer in answers:
@@ -3073,7 +3073,7 @@ def collection_mark_overview(request, pk):
{ {
"collection": collection, "collection": collection,
"answers": answers, "answers": answers,
"case_details": case_details, "casedetails": casedetails,
"case_map": case_map, "case_map": case_map,
}, },
) )
@@ -3091,9 +3091,9 @@ def collection_mark_question(request, pk, case_number):
previous = case_number > 0 previous = case_number > 0
next = case_number < (case_count - 1) next = case_number < (case_count - 1)
case_detail = CaseDetail.objects.filter(case=case, collection=collection) casedetail = CaseDetail.objects.filter(case=case, collection=collection)
answers = CidReportAnswer.objects.filter(question__in=case_detail) answers = CidReportAnswer.objects.filter(question__in=casedetail)
answer_forms = [] answer_forms = []
if request.method == "POST": if request.method == "POST":
@@ -3107,7 +3107,7 @@ def collection_mark_question(request, pk, case_number):
if form.is_valid(): if form.is_valid():
answer = form.save(commit=False) answer = form.save(commit=False)
# answer.cid = cid # answer.cid = cid
# answer.question = case_detail # answer.question = casedetail
# answer.published_date = timezone.now() # answer.published_date = timezone.now()
answer.save() answer.save()
@@ -3145,7 +3145,7 @@ def collection_mark_question(request, pk, case_number):
"collection": collection, "collection": collection,
"series_list": series_list, "series_list": series_list,
"answers": answers, "answers": answers,
"case_detail": case_detail, "casedetail": casedetail,
"case": case, "case": case,
"case_number": case_number, "case_number": case_number,
"answer_forms": answer_forms, "answer_forms": answer_forms,
@@ -3228,13 +3228,13 @@ def collection_take_overview(
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) casedetails = CaseDetail.objects.filter(case__in=cases, collection=collection)
if cid is not None: if cid is not None:
answers = CidReportAnswer.objects.filter(cid=cid, question__in=case_details) answers = CidReportAnswer.objects.filter(cid=cid, question__in=casedetails)
else: else:
answers = UserReportAnswer.objects.filter( answers = UserReportAnswer.objects.filter(
user=request.user, question__in=case_details user=request.user, question__in=casedetails
) )
answer_question_map = {} answer_question_map = {}
@@ -3243,7 +3243,7 @@ def collection_take_overview(
question_answer_tuples = [] question_answer_tuples = []
answer_count = 0 answer_count = 0
for cd in case_details: for cd in casedetails:
self_review = cid_user_exam.selfreview_set.filter(case=cd.case) self_review = cid_user_exam.selfreview_set.filter(case=cd.case)
if cd in answer_question_map and ( if cd in answer_question_map and (
answer_question_map[cd].answer or answer_question_map[cd].json_answer answer_question_map[cd].answer or answer_question_map[cd].json_answer
@@ -3290,7 +3290,7 @@ def collection_case_view_take_answers(
cid=cid, user_user=request.user cid=cid, user_user=request.user
) )
case_detail = CaseDetail.objects.get(case=case, collection=collection) casedetail = CaseDetail.objects.get(case=case, collection=collection)
return render( return render(
request, request,
@@ -3298,7 +3298,7 @@ def collection_case_view_take_answers(
{ {
"collection": collection, "collection": collection,
"case": case, "case": case,
"case_detail": case_detail, "casedetail": casedetail,
}, },
) )
@@ -3347,23 +3347,23 @@ def collection_case_view_take(
cid_user_exam.start_time = timezone.now() cid_user_exam.start_time = timezone.now()
cid_user_exam.save() cid_user_exam.save()
case_detail = CaseDetail.objects.get(case=case, collection=collection) casedetail = CaseDetail.objects.get(case=case, collection=collection)
if not collection.review_only(): if not collection.review_only():
if collection.collection_type == "REP": if collection.collection_type == "REP":
if cid is not None: if cid is not None:
answer = case_detail.cidreportanswer_set.filter(cid=cid).first() answer = casedetail.cidreportanswer_set.filter(cid=cid).first()
ReportAnswerForm = CidReportAnswerForm ReportAnswerForm = CidReportAnswerForm
else: else:
answer = case_detail.userreportanswer_set.filter( answer = casedetail.userreportanswer_set.filter(
user=request.user user=request.user
).first() ).first()
ReportAnswerForm = UserReportAnswerForm ReportAnswerForm = UserReportAnswerForm
elif collection.collection_type == "QUE": elif collection.collection_type == "QUE":
if cid is not None: if cid is not None:
answer = case_detail.cidreportanswer_set.filter(cid=cid).first() answer = casedetail.cidreportanswer_set.filter(cid=cid).first()
ReportAnswerForm = CidQuestionAnswerForm ReportAnswerForm = CidQuestionAnswerForm
else: else:
answer = case_detail.userreportanswer_set.filter( answer = casedetail.userreportanswer_set.filter(
user=request.user user=request.user
).first() ).first()
ReportAnswerForm = UserQuestionAnswerForm ReportAnswerForm = UserQuestionAnswerForm
@@ -3381,9 +3381,9 @@ def collection_case_view_take(
if not answer and collection.collection_type in ("REP", "QUE"): if not answer and collection.collection_type in ("REP", "QUE"):
try: try:
if cid is not None: if cid is not None:
answer = CidReportAnswer(question=case_detail, cid=cid) answer = CidReportAnswer(question=casedetail, cid=cid)
else: else:
answer = UserReportAnswer(question=case_detail, user=request.user) answer = UserReportAnswer(question=casedetail, user=request.user)
answer.started_at = timezone.now() answer.started_at = timezone.now()
answer.save() answer.save()
except Exception: except Exception:
@@ -3396,10 +3396,10 @@ def collection_case_view_take(
if not collection.publish_results: if not collection.publish_results:
if answer: if answer:
form = ReportAnswerForm( form = ReportAnswerForm(
request.POST, instance=answer, case_detail=case_detail request.POST, instance=answer, casedetail=casedetail
) )
else: else:
form = ReportAnswerForm(request.POST, case_detail=case_detail) form = ReportAnswerForm(request.POST, casedetail=casedetail)
if not cid_user_exam.completed and not ( if not cid_user_exam.completed and not (
answer is not None and answer.completed answer is not None and answer.completed
@@ -3407,7 +3407,7 @@ def collection_case_view_take(
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)
answer.question = case_detail answer.question = casedetail
# Record submission timestamp # Record submission timestamp
answer.submitted_at = timezone.now() answer.submitted_at = timezone.now()
# answer.published_date = timezone.now() # answer.published_date = timezone.now()
@@ -3478,7 +3478,7 @@ def collection_case_view_take(
) )
else: else:
if collection.collection_type in ("REP", "QUE"): if collection.collection_type in ("REP", "QUE"):
form = ReportAnswerForm(instance=answer, case_detail=case_detail) form = ReportAnswerForm(instance=answer, casedetail=casedetail)
series_list = case.series.all().prefetch_related("images", "examination", "plane") series_list = case.series.all().prefetch_related("images", "examination", "plane")
@@ -3517,7 +3517,7 @@ def collection_case_view_take(
resources = case.caseresource_set.filter(pre_review=True) resources = case.caseresource_set.filter(pre_review=True)
prior_cases = case_detail.caseprior_set.all() prior_cases = casedetail.caseprior_set.all()
series_to_load = [] series_to_load = []
@@ -3543,7 +3543,7 @@ def collection_case_view_take(
"form": form, "form": form,
"collection": collection, "collection": collection,
"case": case, "case": case,
"case_detail": case_detail, "casedetail": casedetail,
"series_list": series_list, "series_list": series_list,
"series_to_load": series_to_load, "series_to_load": series_to_load,
"case_number": case_number, "case_number": case_number,
@@ -3636,14 +3636,14 @@ def collection_case_dicom_json_review(request, exam_id, case_id):
return collection_case_dicom_json(request, exam_id, case_id, review=True) return collection_case_dicom_json(request, exam_id, case_id, review=True)
def collection_case_dicom_json(request, exam_id, case_id, review=False): def collection_case_dicom_json(request, exam_id, case_id, review=False):
case_detail = CaseDetail.objects.get(case=case_id, collection=exam_id) casedetail = CaseDetail.objects.get(case=case_id, collection=exam_id)
if review: if review:
priors = case_detail.caseprior_set.exclude(prior_visibility="NO") priors = casedetail.caseprior_set.exclude(prior_visibility="NO")
else: else:
priors = case_detail.caseprior_set.exclude(prior_visibility__in=["NO", "RE"]) priors = casedetail.caseprior_set.exclude(prior_visibility__in=["NO", "RE"])
return JsonResponse(case_detail.case.get_case_dicom_json(priors=priors)) return JsonResponse(casedetail.case.get_case_dicom_json(priors=priors))
def case_dicom_json(request, pk): def case_dicom_json(request, pk):
@@ -3664,12 +3664,12 @@ def delete_collection_cid_answers(request, exam_id, cid):
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( casedetails = CaseDetail.objects.filter(
case__in=cases, collection=collection case__in=cases, collection=collection
).prefetch_related("case") ).prefetch_related("case")
cid_user_answers = CidReportAnswer.objects.filter( cid_user_answers = CidReportAnswer.objects.filter(
question__in=case_details, cid=cid question__in=casedetails, cid=cid
) )
temp = {} temp = {}
@@ -3686,11 +3686,11 @@ def delete_collection_answers(request, exam_id):
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( casedetails = CaseDetail.objects.filter(
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_user_answers = CidReportAnswer.objects.filter(question__in=casedetails)
temp = {} temp = {}
for ans in cid_user_answers: for ans in cid_user_answers:
@@ -3719,11 +3719,11 @@ def collection_scores_cid(request, pk):
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( casedetails = CaseDetail.objects.filter(
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_user_answers = CidReportAnswer.objects.filter(question__in=casedetails)
cids = set() cids = set()
@@ -4126,7 +4126,7 @@ def collection_question_schemas(request, exam_id: int):
questions = collection.cases.all().prefetch_related() questions = collection.cases.all().prefetch_related()
case_details = ( casedetails = (
CaseDetail.objects.filter(case__in=questions, collection=collection) CaseDetail.objects.filter(case__in=questions, collection=collection)
.prefetch_related("case") .prefetch_related("case")
.order_by("sort_order") .order_by("sort_order")
@@ -4137,7 +4137,7 @@ def collection_question_schemas(request, exam_id: int):
"atlas/collection_question_schemas.html", "atlas/collection_question_schemas.html",
{ {
"collection": collection, "collection": collection,
"case_details": case_details, "casedetails": casedetails,
}, },
) )
@@ -4255,10 +4255,10 @@ def collection_reset_answers_user(request, exam_id: int, user_id: int):
collection = get_object_or_404(CaseCollection, pk=exam_id) collection = get_object_or_404(CaseCollection, pk=exam_id)
# Select all case details (answers are linked to these) # Select all case details (answers are linked to these)
case_details = collection.casedetail_set.all().prefetch_related() casedetails = collection.casedetail_set.all().prefetch_related()
# Delete all answers # Delete all answers
for case in case_details: for case in casedetails:
user_answers = case.userreportanswer_set.filter(user_id=user_id) user_answers = case.userreportanswer_set.filter(user_id=user_id)
user_answers.delete() user_answers.delete()
@@ -4276,10 +4276,10 @@ def collection_reset_answers_ciduser(request, exam_id: int, cid: int):
collection = get_object_or_404(CaseCollection, pk=exam_id) collection = get_object_or_404(CaseCollection, pk=exam_id)
# Select all case details (answers are linked to these) # Select all case details (answers are linked to these)
case_details = collection.casedetail_set.all().prefetch_related() casedetails = collection.casedetail_set.all().prefetch_related()
# Delete all answers # Delete all answers
for case in case_details: for case in casedetails:
cid_answers = case.cidreportanswer_set.filter(cid=cid) cid_answers = case.cidreportanswer_set.filter(cid=cid)
cid_answers.delete() cid_answers.delete()
@@ -4297,10 +4297,10 @@ def collection_reset_answers(request, exam_id: int):
collection = get_object_or_404(CaseCollection, pk=exam_id) collection = get_object_or_404(CaseCollection, pk=exam_id)
# Select all case details (answers are linked to these) # Select all case details (answers are linked to these)
case_details = collection.casedetail_set.all().prefetch_related() casedetails = collection.casedetail_set.all().prefetch_related()
# Delete all answers # Delete all answers
for case in case_details: for case in casedetails:
cid_answers = case.cidreportanswer_set.all() cid_answers = case.cidreportanswer_set.all()
cid_answers.delete() cid_answers.delete()
@@ -4522,22 +4522,38 @@ def collection_case_displaysetup(request, collection_id, case_id):
View to set up the display options for a specific case in a collection. View to set up the display options for a specific case in a collection.
This can include setting which series to display, annotations, etc. This can include setting which series to display, annotations, etc.
""" """
case_detail = get_object_or_404(CaseDetail, case__pk=case_id, collection__pk=collection_id) casedetail = get_object_or_404(CaseDetail, case__pk=case_id, collection__pk=collection_id)
if request.method == "POST": if request.method == "POST":
data = json.loads(request.body.decode("utf-8")) data = json.loads(request.body.decode("utf-8"))
if data.get("reset_viewerstate"): if data.get("reset_viewerstate"):
case_detail.default_viewerstate = None casedetail.default_viewerstate = None
case_detail.save() casedetail.save()
return HttpResponse("<span class='text-success'>Viewer state reset to default.</span>") return HttpResponse("<span class='text-success'>Viewer state reset to default.</span>")
viewerstate = data.get("viewerstate") viewerstate = data.get("viewerstate")
if viewerstate is not None: if viewerstate is not None:
case_detail.default_viewerstate = viewerstate casedetail.default_viewerstate = viewerstate
case_detail.save() casedetail.save()
return HttpResponse("<span class='text-success'>Viewer state saved.</span>") return HttpResponse("<span class='text-success'>Viewer state saved.</span>")
else: else:
return HttpResponse("<span class='text-danger'>No viewer state provided.</span>", status=400) return HttpResponse("<span class='text-danger'>No viewer state provided.</span>", status=400)
collection = casedetail.collection
case_number, case_count = collection.get_index_of_case(
casedetail.case, case_count=True
)
previous = collection.get_previous_case(casedetail.case)
next = collection.get_next_case(casedetail.case)
return render(request, "atlas/collection_case_displaysetup.html", { return render(request, "atlas/collection_case_displaysetup.html", {
"case_detail": case_detail "casedetail": casedetail,
"collection": collection,
"case_number": case_number,
"case_count": case_count,
"previous": previous,
"next": next,
"collection_length": case_count,
}) })