Refactor exam search widget: simplify model retrieval and remove redundant code

This commit is contained in:
Ross
2026-02-16 12:03:57 +00:00
parent f2eaf6197e
commit 8ba9543c89
+7 -69
View File
@@ -91,6 +91,8 @@ from .forms import (
ExamCollectionBulkAddGroupsForm,
)
from loguru import logger
from .models import (
CidUser,
CidUserExam,
@@ -6656,18 +6658,7 @@ def exam_search_widget(request):
# Support wildcard queries
q = q_raw
model = None
if model_label:
try:
# model_label may be 'app_label.ModelName' or the model label
model = apps.get_model(model_label)
except Exception:
try:
# try splitting
app_label, model_name = model_label.split(".")
model = apps.get_model(app_label, model_name)
except Exception:
model = None
model = apps.get_model(model_label)
# Helper to parse optional boolean GET params
def _get_bool_param(name):
@@ -6690,64 +6681,11 @@ def exam_search_widget(request):
# Build queryset
qs = None
if model is not None:
field_lookups = ["name__icontains"]
for lookup in field_lookups:
qs = model.objects.filter(**{lookup: q})
if qs.exists():
field_lookups = ["name__icontains"]
for lookup in field_lookups:
qs = model.objects.filter(**{lookup: q})
if qs.exists():
break
else:
# If no model specified, try to search across several known exam models
possible_models = [
"anatomy.Exam",
"longs.Exam",
"rapids.Exam",
"shorts.Exam",
"physics.Exam",
"sbas.Exam",
]
results = []
# gather optional filters from GET params
extra_filters = {}
for pname in ("archive", "open_access", "exam_mode", "candidates_only"):
val = _get_bool_param(pname)
if val is not None:
extra_filters[pname] = val
for ml in possible_models:
try:
m = apps.get_model(*ml.split("."))
except Exception:
continue
try:
# try common name-like fields and apply extra_filters when possible
try:
rqs = m.objects.filter(name__icontains=q, **extra_filters)[:5]
except Exception:
try:
rqs = m.objects.filter(title__icontains=q, **extra_filters)[:5]
except Exception:
# fallback to unfiltered small slice
rqs = m.objects.filter(name__icontains=q)[:5]
except Exception:
rqs = m.objects.none()
for o in rqs:
results.append(o)
rendered_results = []
for o in results[:50]:
if user_can_view_exam(o, request.user):
rendered_results.append({
"id": getattr(o, "pk", None),
"text": str(o),
"archive": getattr(o, "archive", False),
"open_access": getattr(o, "open_access", False),
"exam_mode": getattr(o, "exam_mode", False),
"candidates_only": getattr(o, "candidates_only", False),
})
return render(request, "generic/partials/exam_search_widget_results.html", {"results": rendered_results, "field": field, "q": q_raw})
logger.error(qs)