Add admin view for cases ordered by total image size with filtering options
This commit is contained in:
@@ -30,6 +30,8 @@ from django.views.generic.detail import DetailView
|
||||
import pydicom
|
||||
from pydicom.uid import generate_uid
|
||||
from generic.mixins import SuperuserRequiredMixin, UserConfigurablePaginationMixin
|
||||
from django.contrib.admin.views.decorators import staff_member_required
|
||||
from django.core.paginator import Paginator
|
||||
|
||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView
|
||||
from django.views.generic import ListView
|
||||
@@ -2304,6 +2306,66 @@ class CaseView(LoginRequiredMixin, UserConfigurablePaginationMixin, SingleTableM
|
||||
filterset_class = CaseFilter
|
||||
|
||||
|
||||
@staff_member_required
|
||||
def cases_by_size(request):
|
||||
"""Admin view: list cases ordered by total images size to find large cases.
|
||||
|
||||
Shows case id, title, number of series, number of images and total size (bytes).
|
||||
Optional GET parameter `min_size` (bytes) to filter cases larger than that.
|
||||
"""
|
||||
min_size = request.GET.get("min_size")
|
||||
try:
|
||||
min_size = int(min_size) if min_size else 0
|
||||
except Exception:
|
||||
min_size = 0
|
||||
|
||||
cases_qs = Case.objects.prefetch_related("series__images")
|
||||
|
||||
def human(n):
|
||||
# simple human readable bytes
|
||||
for unit in ("B", "KB", "MB", "GB", "TB"):
|
||||
if n < 1024.0:
|
||||
return f"{n:.1f}{unit}"
|
||||
n /= 1024.0
|
||||
return f"{n:.1f}PB"
|
||||
|
||||
rows = []
|
||||
for c in cases_qs:
|
||||
try:
|
||||
total = c.get_total_series_images_size()
|
||||
except Exception:
|
||||
total = 0
|
||||
series_count = c.series.count()
|
||||
image_count = sum(s.images.filter(removed=False).count() for s in c.series.all())
|
||||
if total >= min_size:
|
||||
rows.append({
|
||||
"case": c,
|
||||
"total": total,
|
||||
"series_count": series_count,
|
||||
"image_count": image_count,
|
||||
"human_total": human(total),
|
||||
})
|
||||
|
||||
rows.sort(key=lambda r: r["total"], reverse=True)
|
||||
|
||||
rows.sort(key=lambda r: r["total"], reverse=True)
|
||||
|
||||
paginator = Paginator(rows, 50)
|
||||
page_num = request.GET.get("page")
|
||||
page = paginator.get_page(page_num)
|
||||
|
||||
def human(n):
|
||||
# simple human readable bytes
|
||||
for unit in ("B", "KB", "MB", "GB", "TB"):
|
||||
if n < 1024.0:
|
||||
return f"{n:.1f}{unit}"
|
||||
n /= 1024.0
|
||||
return f"{n:.1f}PB"
|
||||
|
||||
context = {"page": page, "human": human, "min_size": min_size}
|
||||
return render(request, "atlas/cases_by_size.html", context)
|
||||
|
||||
|
||||
class SeriesView(LoginRequiredMixin, UserConfigurablePaginationMixin, SingleTableMixin, FilterView):
|
||||
model = Series
|
||||
table_class = SeriesTable
|
||||
|
||||
Reference in New Issue
Block a user