lots of improvements

This commit is contained in:
Ross
2025-07-14 13:26:11 +01:00
parent ec97fa0c71
commit 5187885c3b
14 changed files with 536 additions and 71 deletions
+135 -19
View File
@@ -9,6 +9,8 @@ from django.shortcuts import render, get_object_or_404, redirect
from django import forms
from django.utils import timezone
from django.views.decorators.http import require_POST
from django.views.decorators.http import require_http_methods
from django.template.loader import render_to_string
# from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required, user_passes_test
@@ -47,6 +49,7 @@ from .forms import (
CaseCollectionCaseFormSet,
CaseCollectionForm,
CaseDetailForm,
CaseDisplaySetForm,
CaseForm,
CaseResourceFormSet,
CaseUpdateSeriesForm,
@@ -77,7 +80,9 @@ from .models import (
Case,
CaseCollection,
CaseDetail,
CaseDisplaySet,
CasePrior,
CaseResource,
CidReportAnswer,
Condition,
Differential,
@@ -196,6 +201,102 @@ class AtlasEditorRequiredMixin(object):
return obj
raise PermissionDenied("You must be an atlas editor to do this.") # or Http404
@login_required
@user_has_case_view_access
def case_displaysets(request, pk):
case = get_object_or_404(Case, pk=pk)
can_edit = case.check_user_can_edit(request.user)
# Get displayset id from GET parameter
displayset_id = request.GET.get("displayset")
selected_displayset = None
if displayset_id:
try:
selected_displayset = case.display_sets.get(pk=displayset_id)
except CaseDisplaySet.DoesNotExist:
selected_displayset = None
return render(
request,
"atlas/case_displaysets.html",
{
"case": case,
"can_edit": can_edit,
"selected_displayset": selected_displayset,
},
)
@login_required
@user_has_case_view_access
@require_http_methods(["GET", "POST"])
def case_displaysets_add(request, pk):
case = get_object_or_404(Case, pk=pk)
form = CaseDisplaySetForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
ds = form.save(commit=False)
ds.case = case
ds.author = request.user
ds.viewerstate = request.POST.get("viewerstate") or None
ds.annotations = request.POST.get("annotations") or None
ds.save()
form.save_m2m()
# HTMX: return the new display set row HTML fragment
html = render_to_string("atlas/partials/displayset_row.html", {"ds": ds, "can_edit": True})
return HttpResponse(html)
else:
# HTMX: return the form HTML fragment with errors
html = render_to_string("atlas/partials/displayset_form.html", {"form": form, "case": case}, request=request)
return HttpResponse(html, status=400)
else:
# HTMX: return the blank form HTML fragment
html = render_to_string("atlas/partials/displayset_form.html", {"form": form, "case": case}, request=request)
return HttpResponse(html)
@login_required
@require_http_methods(["GET", "POST"])
def case_displaysets_edit(request, pk):
ds = get_object_or_404(CaseDisplaySet, pk=pk)
case = ds.case
if not case.check_user_can_edit(request.user):
return HttpResponse("You do not have permission to delete this display set.")
form = CaseDisplaySetForm(request.POST or None, instance=ds)
if request.method == "POST":
if form.is_valid():
ds = form.save(commit=False)
ds.viewerstate = request.POST.get("viewerstate") or ds.viewerstate
ds.annotations = request.POST.get("annotations") or ds.annotations
ds.save()
form.save_m2m()
# Return updated row HTML
html = render_to_string("atlas/partials/displayset_row.html", {"ds": ds, "can_edit": True}, request=request)
return HttpResponse(html)
else:
html = render_to_string("atlas/partials/displayset_form.html", {"form": form, "case": case}, request=request)
return HttpResponse(html, status=400)
else:
html = render_to_string("atlas/partials/displayset_form.html", {"form": form, "case": case}, request=request)
return HttpResponse(html)
@require_http_methods(["GET", "POST"])
def case_displaysets_detail(request, pk):
displayset = get_object_or_404(CaseDisplaySet, pk=pk)
case = displayset.case
# Redirect to the case_displaysets page with ?displayset=<pk>
return redirect(f"{reverse('atlas:case_displaysets', args=[case.pk])}?displayset={pk}")
def case_displaysets_delete(request, pk):
try:
displayset = CaseDisplaySet.objects.get(pk=pk)
except CaseDisplaySet.DoesNotExist:
raise Http404("Display set not found.")
if not displayset.case.check_user_can_edit(request.user):
raise PermissionDenied("You do not have permission to delete this display set.")
displayset.delete()
return HttpResponse("<li class='list-group-item' >Display set deleted successfully.")
@login_required
@user_has_case_view_access
@@ -205,25 +306,40 @@ def case_detail(request, pk):
Case.objects
.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",
Prefetch(
"seriesdetail_set",
queryset=SeriesDetail.objects.select_related("series").order_by("sort_order").prefetch_related(
Prefetch(
"series",
queryset=Series.objects.select_related("modality", "examination", "plane", "contrast")
.prefetch_related(
Prefetch("images", queryset=SeriesImage.objects.filter(removed=False).order_by("position")),
Prefetch(
"findings",
queryset=SeriesFinding.objects.prefetch_related(
Prefetch("findings", queryset=Finding.objects.all()),
Prefetch("conditions", queryset=Condition.objects.all()),
Prefetch("structures", queryset=Structure.objects.all()),
)
),
)
),
),
),
Prefetch("subspecialty", queryset=Subspecialty.objects.all()),
Prefetch("condition", queryset=Condition.objects.all()),
Prefetch("presentation", queryset=Presentation.objects.all()),
Prefetch("pathological_process", queryset=PathologicalProcess.objects.all()),
Prefetch("caseresource_set", queryset=CaseResource.objects.all()),
Prefetch("casecollection_set", queryset=CaseCollection.objects.all()),
Prefetch("display_sets", queryset=CaseDisplaySet.objects.prefetch_related(
Prefetch("findings", queryset=Finding.objects.all()),
Prefetch("structures", queryset=Structure.objects.all()),
Prefetch("conditions", queryset=Condition.objects.all()),
)),
)
.get(pk=pk)
)
can_edit = case.check_user_can_edit(request.user)
return render(
@@ -3349,7 +3465,7 @@ def series_bulk_delete(request):
@user_is_collection_author_or_atlas_editor
@csrf_exempt # Only if you have CSRF issues; otherwise, keep CSRF protection
def collection_case_display_setup(request, collection_id, case_id):
def collection_case_displaysetup(request, collection_id, case_id):
"""
View to set up the display options for a specific case in a collection.
This can include setting which series to display, annotations, etc.
@@ -3370,6 +3486,6 @@ def collection_case_display_setup(request, collection_id, case_id):
else:
return HttpResponse("<span class='text-danger'>No viewer state provided.</span>", status=400)
return render(request, "atlas/collection_case_display_setup.html", {
return render(request, "atlas/collection_case_displaysetup.html", {
"case_detail": case_detail
})
})