Enhance NormalCaseFilter to limit examination and modality choices based on user restrictions; integrate Crispy Forms for improved filter form layout in normals_list template
This commit is contained in:
+45
-3
@@ -1,4 +1,6 @@
|
||||
import django_filters
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Layout, Div
|
||||
|
||||
from .models import (
|
||||
Case,
|
||||
@@ -364,9 +366,10 @@ class NormalCaseFilter(django_filters.FilterSet):
|
||||
# Use the global Examination and Modality querysets from the Series model
|
||||
from generic.models import Examination, Modality
|
||||
|
||||
# Set up the actual querysets for the filters
|
||||
self.base_filters.get("examination").queryset = Examination.objects.all()
|
||||
self.base_filters.get("modality").queryset = Modality.objects.all()
|
||||
# We'll set the actual querysets for the filters after applying
|
||||
# any NormalCase queryset restrictions for the current user so
|
||||
# that the choices only include examinations/modalities that
|
||||
# actually have NormalCase records available.
|
||||
|
||||
# If not an atlas editor restrict to cases authored by the user or open access cases
|
||||
if request is not None and not request.user.groups.filter(name="atlas_editor").exists():
|
||||
@@ -376,8 +379,47 @@ class NormalCaseFilter(django_filters.FilterSet):
|
||||
queryset = NormalCase.objects.select_related("case")
|
||||
queryset = queryset.filter((Q(case__author__id=request.user.id) | Q(case__open_access=True)))
|
||||
|
||||
# Determine the NormalCase queryset we'll use to build choices
|
||||
nc_qs = queryset if queryset is not None else NormalCase.objects.all()
|
||||
|
||||
# Limit examination and modality choices to those present on the
|
||||
# available NormalCase records (respecting user restrictions).
|
||||
try:
|
||||
exam_ids = nc_qs.values_list("examination_id", flat=True)
|
||||
mod_ids = nc_qs.values_list("modality_id", flat=True)
|
||||
self.base_filters.get("examination").queryset = Examination.objects.filter(id__in=exam_ids).distinct()
|
||||
self.base_filters.get("modality").queryset = Modality.objects.filter(id__in=mod_ids).distinct()
|
||||
except Exception:
|
||||
# Fallback to all if something goes wrong
|
||||
self.base_filters.get("examination").queryset = Examination.objects.all()
|
||||
self.base_filters.get("modality").queryset = Modality.objects.all()
|
||||
|
||||
super(NormalCaseFilter, self).__init__(data=data, queryset=queryset, prefix=prefix, request=request)
|
||||
|
||||
# Attach a Crispy FormHelper to render the filter form as a
|
||||
# horizontal Bootstrap grid. We set `form_tag=False` because the
|
||||
# template already provides the <form> element.
|
||||
try:
|
||||
helper = FormHelper()
|
||||
helper.form_method = "get"
|
||||
helper.form_tag = False
|
||||
helper.form_class = "row g-2 align-items-end"
|
||||
helper.layout = Layout(
|
||||
Div(
|
||||
Div("examination", css_class="col-md-4"),
|
||||
Div("modality", css_class="col-md-4"),
|
||||
Div("age_days", css_class="col-md-2"),
|
||||
Div("min_age", css_class="col-md-2"),
|
||||
Div("max_age", css_class="col-md-2"),
|
||||
css_class="row g-2 align-items-end",
|
||||
)
|
||||
)
|
||||
# Assign helper to the generated form instance
|
||||
if hasattr(self, 'form') and self.form is not None:
|
||||
self.form.helper = helper
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def filter_min_age(self, queryset, name, value):
|
||||
try:
|
||||
days = int(float(value) * 365.25)
|
||||
|
||||
@@ -9,12 +9,7 @@
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4">
|
||||
<form method="get" class="form-inline">
|
||||
{% for field in filter.form.visible_fields %}
|
||||
<div class="mb-2">
|
||||
{{ field.label_tag }}
|
||||
{{ field }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% crispy filter.form %}
|
||||
<div class="mb-2">
|
||||
<button class="btn btn-primary" type="submit">Filter</button>
|
||||
<a class="btn btn-link" href="?">Clear</a>
|
||||
|
||||
Reference in New Issue
Block a user