some updates
This commit is contained in:
+99
-32
@@ -32,6 +32,7 @@ from atlas.models import (
|
|||||||
Resource,
|
Resource,
|
||||||
SelfReview,
|
SelfReview,
|
||||||
Series,
|
Series,
|
||||||
|
SeriesDetail,
|
||||||
SeriesImage,
|
SeriesImage,
|
||||||
SeriesFinding,
|
SeriesFinding,
|
||||||
Condition,
|
Condition,
|
||||||
@@ -296,6 +297,31 @@ class SeriesForm(ModelForm):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#def save(self, commit=True):
|
||||||
|
# # Get the unsaved Case instance
|
||||||
|
# instance = ModelForm.save(self, False)
|
||||||
|
|
||||||
|
|
||||||
|
# # Prepare a 'save_m2m' method for the form,
|
||||||
|
# old_save_m2m = self.save_m2m
|
||||||
|
|
||||||
|
# def save_m2m():
|
||||||
|
# old_save_m2m()
|
||||||
|
# # instance.exams.clear()
|
||||||
|
# # for exam in self.cleaned_data["exams"]:
|
||||||
|
# # # We need the id here
|
||||||
|
# # instance.exams.add(exam.pk)
|
||||||
|
|
||||||
|
# self.save_m2m = save_m2m
|
||||||
|
|
||||||
|
# # Do we need to save all changes now?
|
||||||
|
# # if commit:
|
||||||
|
# instance.save()
|
||||||
|
# self.save_m2m()
|
||||||
|
|
||||||
|
|
||||||
|
# return instance
|
||||||
|
|
||||||
class CaseForm(ModelForm):
|
class CaseForm(ModelForm):
|
||||||
|
|
||||||
class Media:
|
class Media:
|
||||||
@@ -523,28 +549,28 @@ class CaseResourceForm(ModelForm):
|
|||||||
self.fields["pre_review"] = BooleanField(required=False)
|
self.fields["pre_review"] = BooleanField(required=False)
|
||||||
|
|
||||||
|
|
||||||
class CaseSeriesForm(ModelForm):
|
#class CaseSeriesForm(ModelForm):
|
||||||
|
#
|
||||||
def __init__(self, *args, user, **kwargs):
|
# def __init__(self, *args, user, **kwargs):
|
||||||
super(CaseSeriesForm, self).__init__(*args, **kwargs)
|
# super(CaseSeriesForm, self).__init__(*args, **kwargs)
|
||||||
|
#
|
||||||
if not user.groups.filter(name="atlas_editor").exists():
|
# if not user.groups.filter(name="atlas_editor").exists():
|
||||||
queryset = Series.objects.filter(author__id=user.id)
|
# queryset = Series.objects.filter(author__id=user.id)
|
||||||
else:
|
# else:
|
||||||
queryset = Series.objects.all()
|
# queryset = Series.objects.all()
|
||||||
|
#
|
||||||
# Optimize the queryset for the ModelChoiceField
|
# # Optimize the queryset for the ModelChoiceField
|
||||||
queryset = queryset.select_related(
|
# queryset = queryset.select_related(
|
||||||
"modality"
|
# "modality"
|
||||||
).prefetch_related(
|
# ).prefetch_related(
|
||||||
"examination", "plane", "contrast", "images"
|
# "examination", "plane", "contrast", "images"
|
||||||
)
|
# )
|
||||||
|
#
|
||||||
self.fields["series"] = ModelChoiceField(
|
# self.fields["series"] = ModelChoiceField(
|
||||||
required=False,
|
# required=False,
|
||||||
queryset=queryset,
|
# queryset=queryset,
|
||||||
# widget=Select(verbose_name="Series", is_stacked=False),
|
# # widget=Select(verbose_name="Series", is_stacked=False),
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -561,15 +587,15 @@ class CaseCollectionCaseForm(ModelForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
SeriesFormSet = inlineformset_factory(
|
#SeriesFormSet = inlineformset_factory(
|
||||||
Case,
|
# Case,
|
||||||
Series.case.through,
|
# Series.case.through,
|
||||||
form=CaseSeriesForm,
|
# form=CaseSeriesForm,
|
||||||
exclude=[],
|
# exclude=[],
|
||||||
can_delete=True,
|
# can_delete=True,
|
||||||
extra=0,
|
# extra=0,
|
||||||
max_num=10,
|
# max_num=10,
|
||||||
)
|
#)
|
||||||
|
|
||||||
CaseCollectionCaseFormSet = inlineformset_factory(
|
CaseCollectionCaseFormSet = inlineformset_factory(
|
||||||
CaseCollection,
|
CaseCollection,
|
||||||
@@ -893,4 +919,45 @@ class PriorCaseForm(Form):
|
|||||||
# self.fields["case"] = ChoiceField(
|
# self.fields["case"] = ChoiceField(
|
||||||
# required=False,
|
# required=False,
|
||||||
# # widget=Select(verbose_name="Series", is_stacked=False),
|
# # widget=Select(verbose_name="Series", is_stacked=False),
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
class CaseSeriesForm(forms.ModelForm):
|
||||||
|
def __init__(self, *args, user=None, is_atlas_editor=False, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
if not is_atlas_editor:
|
||||||
|
queryset = Series.objects.filter(author__id=user.id)
|
||||||
|
else:
|
||||||
|
queryset = Series.objects.all()
|
||||||
|
queryset = queryset.select_related("modality").prefetch_related(
|
||||||
|
"examination", "plane", "contrast", "images"
|
||||||
|
)
|
||||||
|
self.fields["series"].queryset = queryset
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = SeriesDetail # through model for Case.series
|
||||||
|
fields = ["series", "sort_order", "feedback"]
|
||||||
|
|
||||||
|
class CaseUpdateSeriesForm(forms.ModelForm):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.user = kwargs.pop("user")
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.helper = FormHelper()
|
||||||
|
self.helper.form_id = "id-case-form"
|
||||||
|
self.helper.form_class = "case-form"
|
||||||
|
self.helper.form_method = "post"
|
||||||
|
self.helper.form_action = "submit"
|
||||||
|
self.helper.form_tag = False
|
||||||
|
self.helper.layout = Layout()
|
||||||
|
class Meta:
|
||||||
|
model = Case
|
||||||
|
fields = [] # No fields, just for compatibility with UpdateView
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SeriesFormSet = inlineformset_factory(
|
||||||
|
Case,
|
||||||
|
SeriesDetail,
|
||||||
|
form=CaseSeriesForm,
|
||||||
|
extra=1,
|
||||||
|
can_delete=True,
|
||||||
|
)
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
{% extends "atlas/base.html" %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
{% load static %}
|
||||||
|
{% block content %}
|
||||||
|
{% include "atlas/question_link_header.html" %}
|
||||||
|
<h2>Update Series for Case: {{ object.title }}</h2>
|
||||||
|
<form method="post" enctype="multipart/form-data" data-bs-theme="dark">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% crispy form form.helper %}
|
||||||
|
{{ series_formset.management_form }}
|
||||||
|
<div id="series_formset">
|
||||||
|
{% for form in series_formset %}
|
||||||
|
<div class="card mb-3 series-form">
|
||||||
|
<div class="card-body">
|
||||||
|
{{ form.non_field_errors }}
|
||||||
|
{{ form.errors }}
|
||||||
|
{{ form|crispy }}
|
||||||
|
{% if form.can_delete %}
|
||||||
|
<div class="form-check mt-2">
|
||||||
|
{{ form.DELETE }} <label for="{{ form.DELETE.id_for_label }}">Delete</label>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
<!-- Empty form template for JS -->
|
||||||
|
<div id="empty-form" style="display:none;">
|
||||||
|
<div class="card mb-3 series-form">
|
||||||
|
<div class="card-body">
|
||||||
|
{{ series_formset.empty_form|crispy }}
|
||||||
|
{% if series_formset.empty_form.can_delete %}
|
||||||
|
<div class="form-check mt-2">
|
||||||
|
{{ series_formset.empty_form.DELETE }} <label for="{{ series_formset.empty_form.DELETE.id_for_label }}">Delete</label>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" id="add-series" class="btn btn-secondary mt-2">Add Series</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Save</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
const addBtn = document.getElementById("add-series");
|
||||||
|
const formsetDiv = document.getElementById("series_formset");
|
||||||
|
const emptyFormDiv = document.getElementById("empty-form");
|
||||||
|
let totalForms = document.getElementById("id_seriesdetail_set-TOTAL_FORMS");
|
||||||
|
|
||||||
|
addBtn.addEventListener("click", function() {
|
||||||
|
let formIdx = parseInt(totalForms.value);
|
||||||
|
let newFormHtml = emptyFormDiv.innerHTML.replace(/__prefix__/g, formIdx);
|
||||||
|
let tempDiv = document.createElement('div');
|
||||||
|
tempDiv.innerHTML = newFormHtml;
|
||||||
|
// Clear the id field value for the new form
|
||||||
|
let idInput = tempDiv.querySelector('input[name$="-id"]');
|
||||||
|
if (idInput) {
|
||||||
|
idInput.value = "";
|
||||||
|
}
|
||||||
|
formsetDiv.appendChild(tempDiv.firstElementChild);
|
||||||
|
totalForms.value = formIdx + 1;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
<span class="series-block">
|
<span class="series-block">
|
||||||
<span>
|
<span>
|
||||||
<span class="series-block-series-number">Series {{ forloop.counter }}:</span><br>
|
<span class="series-block-series-number">Series {{ forloop.counter }}:</span><br>
|
||||||
|
test
|
||||||
{{series.get_block}}
|
{{series.get_block}}
|
||||||
<br />
|
<br />
|
||||||
{% comment %} <button class="show-series no-padding text-secondary border-secondary" data-case={{case.pk}} data-target="/ohif/viewer/dicomjson?url=https://www.penracourses.org.uk{% url 'atlas:series_dicom_json' series.pk %}">
|
{% comment %} <button class="show-series no-padding text-secondary border-secondary" data-case={{case.pk}} data-target="/ohif/viewer/dicomjson?url=https://www.penracourses.org.uk{% url 'atlas:series_dicom_json' series.pk %}">
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<div class="floating-header">
|
<div class="floating-header">
|
||||||
<a href="{% url 'atlas:case_detail' pk=case.pk %}" title="View the Case">View</a>
|
<a href="{% url 'atlas:case_detail' pk=case.pk %}" title="View the Case">View</a>
|
||||||
<a href="{% url 'atlas:case_update' pk=case.pk %}" title="Edit the Case">Edit</a>
|
<a href="{% url 'atlas:case_update' pk=case.pk %}" title="Edit the Case">Edit</a>
|
||||||
|
<a href="{% url 'atlas:case_series_update' pk=case.pk %}" title="Edit the Cases Series">Series</a>
|
||||||
<a href="{% url 'atlas:case_clone' pk=case.pk %}"
|
<a href="{% url 'atlas:case_clone' pk=case.pk %}"
|
||||||
title="Clone the Case (duplicate everything but the images)">Clone</a>
|
title="Clone the Case (duplicate everything but the images)">Clone</a>
|
||||||
<a href="{% url 'atlas:case_delete' pk=case.pk %}" title="Delete the Case">Delete</a>
|
<a href="{% url 'atlas:case_delete' pk=case.pk %}" title="Delete the Case">Delete</a>
|
||||||
|
|||||||
@@ -419,6 +419,11 @@ urlpatterns = [
|
|||||||
views.AtlasUpdate.as_view(),
|
views.AtlasUpdate.as_view(),
|
||||||
name="case_update",
|
name="case_update",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"case/<int:pk>/update/series",
|
||||||
|
views.AtlasSeriesUpdate.as_view(),
|
||||||
|
name="case_series_update",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"series/<int:pk>/update",
|
"series/<int:pk>/update",
|
||||||
views.SeriesUpdate.as_view(),
|
views.SeriesUpdate.as_view(),
|
||||||
|
|||||||
+105
-24
@@ -48,6 +48,7 @@ from .forms import (
|
|||||||
CaseDetailForm,
|
CaseDetailForm,
|
||||||
CaseForm,
|
CaseForm,
|
||||||
CaseResourceFormSet,
|
CaseResourceFormSet,
|
||||||
|
CaseUpdateSeriesForm,
|
||||||
CidQuestionAnswerForm,
|
CidQuestionAnswerForm,
|
||||||
CidReportAnswerForm,
|
CidReportAnswerForm,
|
||||||
CidReportAnswerMarkForm,
|
CidReportAnswerMarkForm,
|
||||||
@@ -197,14 +198,32 @@ class AtlasEditorRequiredMixin(object):
|
|||||||
@login_required
|
@login_required
|
||||||
@user_has_case_view_access
|
@user_has_case_view_access
|
||||||
def case_detail(request, pk):
|
def case_detail(request, pk):
|
||||||
case = get_object_or_404(Case, pk=pk)
|
# Prefetch all related objects needed for the template
|
||||||
|
case = (
|
||||||
# if request.user not in atlas.author.all():
|
Case.objects
|
||||||
# raise PermissionDenied
|
.select_related() # Add any FK fields if needed
|
||||||
|
.prefetch_related(
|
||||||
|
"series__examination",
|
||||||
|
"series__plane",
|
||||||
|
"series__contrast",
|
||||||
|
"series__images",
|
||||||
|
"series__findings__findings",
|
||||||
|
"series__findings__conditions",
|
||||||
|
"series__findings__structures",
|
||||||
|
"subspecialty",
|
||||||
|
"condition",
|
||||||
|
"presentation",
|
||||||
|
"pathological_process",
|
||||||
|
#"differential",
|
||||||
|
"caseresource_set",
|
||||||
|
"author",
|
||||||
|
"casecollection_set",
|
||||||
|
)
|
||||||
|
.get(pk=pk)
|
||||||
|
)
|
||||||
|
|
||||||
can_edit = case.check_user_can_edit(request.user)
|
can_edit = case.check_user_can_edit(request.user)
|
||||||
|
|
||||||
# logging.debug(atlas.subspecialty.first().name.all())
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"atlas/case_detail.html",
|
"atlas/case_detail.html",
|
||||||
@@ -215,7 +234,6 @@ def case_detail(request, pk):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@user_is_author_or_atlas_series_checker_or_atlas_marker_or_open_access
|
@user_is_author_or_atlas_series_checker_or_atlas_marker_or_open_access
|
||||||
def series_thumbnail_fail(request, pk):
|
def series_thumbnail_fail(request, pk):
|
||||||
@@ -1023,6 +1041,7 @@ class AtlasCreateBase(RevisionMixin, LoginRequiredMixin):
|
|||||||
|
|
||||||
|
|
||||||
# @login_required
|
# @login_required
|
||||||
|
# CaseCreate
|
||||||
class AtlasCreate(AtlasCreateBase, CreateView):
|
class AtlasCreate(AtlasCreateBase, CreateView):
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
if "pk" in self.kwargs:
|
if "pk" in self.kwargs:
|
||||||
@@ -1041,6 +1060,7 @@ class AtlasCreate(AtlasCreateBase, CreateView):
|
|||||||
# return self.initial
|
# return self.initial
|
||||||
|
|
||||||
|
|
||||||
|
# CaseUpdate
|
||||||
class AtlasUpdate(
|
class AtlasUpdate(
|
||||||
RevisionMixin, LoginRequiredMixin, AuthorOrCheckerRequiredMixin, UpdateView
|
RevisionMixin, LoginRequiredMixin, AuthorOrCheckerRequiredMixin, UpdateView
|
||||||
):
|
):
|
||||||
@@ -1079,12 +1099,12 @@ class AtlasUpdate(
|
|||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(AtlasUpdate, self).get_context_data(**kwargs)
|
context = super(AtlasUpdate, self).get_context_data(**kwargs)
|
||||||
if self.request.POST:
|
if self.request.POST:
|
||||||
context["series_formset"] = SeriesFormSet(
|
#context["series_formset"] = SeriesFormSet(
|
||||||
self.request.POST,
|
# self.request.POST,
|
||||||
self.request.FILES,
|
# self.request.FILES,
|
||||||
instance=self.object,
|
# instance=self.object,
|
||||||
form_kwargs={"user": self.request.user},
|
# form_kwargs={"user": self.request.user},
|
||||||
)
|
#)
|
||||||
context["casedifferential_formset"] = CaseDifferentialFormSet(
|
context["casedifferential_formset"] = CaseDifferentialFormSet(
|
||||||
self.request.POST, self.request.FILES, instance=self.object
|
self.request.POST, self.request.FILES, instance=self.object
|
||||||
)
|
)
|
||||||
@@ -1094,13 +1114,13 @@ class AtlasUpdate(
|
|||||||
instance=self.object,
|
instance=self.object,
|
||||||
form_kwargs={"user": self.request.user},
|
form_kwargs={"user": self.request.user},
|
||||||
)
|
)
|
||||||
context["series_formset"].full_clean()
|
#context["series_formset"].full_clean()
|
||||||
context["casedifferential_formset"].full_clean()
|
context["casedifferential_formset"].full_clean()
|
||||||
context["caseresource_formset"].full_clean()
|
context["caseresource_formset"].full_clean()
|
||||||
else:
|
else:
|
||||||
context["series_formset"] = SeriesFormSet(
|
#context["series_formset"] = SeriesFormSet(
|
||||||
instance=self.object, form_kwargs={"user": self.request.user}
|
# instance=self.object, form_kwargs={"user": self.request.user}
|
||||||
)
|
#)
|
||||||
context["casedifferential_formset"] = CaseDifferentialFormSet(
|
context["casedifferential_formset"] = CaseDifferentialFormSet(
|
||||||
instance=self.object
|
instance=self.object
|
||||||
)
|
)
|
||||||
@@ -1117,18 +1137,18 @@ class AtlasUpdate(
|
|||||||
form.instance.author.add(self.request.user.id)
|
form.instance.author.add(self.request.user.id)
|
||||||
|
|
||||||
context = self.get_context_data(form=form)
|
context = self.get_context_data(form=form)
|
||||||
series_formset = context["series_formset"]
|
#series_formset = context["series_formset"]
|
||||||
casedifferential_formset = context["casedifferential_formset"]
|
casedifferential_formset = context["casedifferential_formset"]
|
||||||
caseresource_formset = context["caseresource_formset"]
|
caseresource_formset = context["caseresource_formset"]
|
||||||
# logger.debug(formset.is_valid())
|
# logger.debug(formset.is_valid())
|
||||||
if (
|
if (
|
||||||
series_formset.is_valid()
|
#series_formset.is_valid()
|
||||||
and casedifferential_formset.is_valid()
|
casedifferential_formset.is_valid()
|
||||||
and caseresource_formset.is_valid()
|
and caseresource_formset.is_valid()
|
||||||
):
|
):
|
||||||
response = super().form_valid(form)
|
response = super().form_valid(form)
|
||||||
series_formset.instance = self.object
|
#series_formset.instance = self.object
|
||||||
series_formset.save()
|
#series_formset.save()
|
||||||
casedifferential_formset.instance = self.object
|
casedifferential_formset.instance = self.object
|
||||||
casedifferential_formset.save()
|
casedifferential_formset.save()
|
||||||
caseresource_formset.instance = self.object
|
caseresource_formset.instance = self.object
|
||||||
@@ -1138,6 +1158,56 @@ class AtlasUpdate(
|
|||||||
else:
|
else:
|
||||||
return super().form_invalid(form)
|
return super().form_invalid(form)
|
||||||
|
|
||||||
|
class AtlasSeriesUpdate(
|
||||||
|
RevisionMixin, LoginRequiredMixin, AuthorOrCheckerRequiredMixin, UpdateView
|
||||||
|
):
|
||||||
|
model = Case
|
||||||
|
form_class = CaseUpdateSeriesForm
|
||||||
|
template_name = "atlas/case_update_series.html"
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
kwargs.update({"user": self.request.user})
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
is_atlas_editor = self.request.user.groups.filter(name="atlas_editor").exists() or self.request.user.is_superuser
|
||||||
|
form_kwargs = {"user": self.request.user, "is_atlas_editor": is_atlas_editor}
|
||||||
|
if self.request.POST:
|
||||||
|
context["series_formset"] = SeriesFormSet(
|
||||||
|
self.request.POST,
|
||||||
|
self.request.FILES,
|
||||||
|
instance=self.object,
|
||||||
|
form_kwargs=form_kwargs,
|
||||||
|
)
|
||||||
|
context["series_formset"].full_clean()
|
||||||
|
else:
|
||||||
|
context["series_formset"] = SeriesFormSet(
|
||||||
|
instance=self.object,
|
||||||
|
form_kwargs=form_kwargs,
|
||||||
|
)
|
||||||
|
return context
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
context = self.get_context_data(form=form)
|
||||||
|
series_formset = context["series_formset"]
|
||||||
|
if series_formset.is_valid():
|
||||||
|
series_formset.instance = self.object
|
||||||
|
series_formset.save()
|
||||||
|
return super().form_valid(form)
|
||||||
|
else:
|
||||||
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
def get_object(self, queryset=None):
|
||||||
|
qs = Case.objects.select_related().prefetch_related(
|
||||||
|
"seriesdetail_set__series__modality",
|
||||||
|
"seriesdetail_set__series__examination",
|
||||||
|
"seriesdetail_set__series__plane",
|
||||||
|
"seriesdetail_set__series__contrast",
|
||||||
|
"seriesdetail_set__series__images",
|
||||||
|
)
|
||||||
|
return qs.get(pk=self.kwargs["pk"])
|
||||||
|
|
||||||
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":
|
||||||
@@ -1642,10 +1712,21 @@ def collection_viva(request, pk):
|
|||||||
# )
|
# )
|
||||||
#)
|
#)
|
||||||
|
|
||||||
casedetails = CaseDetail.objects.filter(collection=collection).order_by(
|
casedetails = (
|
||||||
"sort_order"
|
CaseDetail.objects
|
||||||
|
.filter(collection=collection)
|
||||||
|
.select_related("case")
|
||||||
|
.order_by("sort_order")
|
||||||
|
.prefetch_related(
|
||||||
|
# Prefetch series and their images directly on the case
|
||||||
|
"case__series",
|
||||||
|
"case__series__modality",
|
||||||
|
"case__series__examination",
|
||||||
|
"case__series__plane",
|
||||||
|
"case__series__contrast",
|
||||||
|
"case__series__images",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
logger.debug(casedetails)
|
|
||||||
|
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
|
|||||||
+6
-1
@@ -496,7 +496,12 @@ class SeriesBase(models.Model):
|
|||||||
return format_html('", "'.join(images))
|
return format_html('", "'.join(images))
|
||||||
|
|
||||||
def get_thumbnail(self, recreate=False, fail_loudly=False):
|
def get_thumbnail(self, recreate=False, fail_loudly=False):
|
||||||
images = self.images.filter(removed=False)
|
# Use prefetched images if available
|
||||||
|
images = getattr(self, '_prefetched_objects_cache', {}).get('images')
|
||||||
|
if images is not None:
|
||||||
|
images = [img for img in images if not img.removed]
|
||||||
|
else:
|
||||||
|
images = self.images.filter(removed=False)
|
||||||
|
|
||||||
if len(images) < 1:
|
if len(images) < 1:
|
||||||
return "No images", 0
|
return "No images", 0
|
||||||
|
|||||||
@@ -2377,7 +2377,6 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
cached_scores = True
|
cached_scores = True
|
||||||
|
|
||||||
valid_cid_users = set(exam.valid_cid_users.all().values_list("cid", flat=True))
|
valid_cid_users = set(exam.valid_cid_users.all().values_list("cid", flat=True))
|
||||||
print(valid_cid_users)
|
|
||||||
valid_user_users = set(exam.valid_user_users.all().values_list("pk", flat=True))
|
valid_user_users = set(exam.valid_user_users.all().values_list("pk", flat=True))
|
||||||
|
|
||||||
if self.app_name in ("rapids"):
|
if self.app_name in ("rapids"):
|
||||||
@@ -2403,7 +2402,6 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
user_ids = set()
|
user_ids = set()
|
||||||
|
|
||||||
cids_user_id_map = {}
|
cids_user_id_map = {}
|
||||||
cids_name_map = {}
|
|
||||||
|
|
||||||
# Loop through all candidates
|
# Loop through all candidates
|
||||||
for cid_user_answer in cid_user_answers:
|
for cid_user_answer in cid_user_answers:
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
{% load django_htmx %}
|
{% load django_htmx %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
{% load auth_extras %}
|
{% load auth_extras %}
|
||||||
<html>
|
<html data-bs-theme="dark">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>
|
<title>
|
||||||
|
|||||||
Reference in New Issue
Block a user