Refactor exam search widget: simplify model retrieval and remove redundant code
This commit is contained in:
+7
-69
@@ -91,6 +91,8 @@ from .forms import (
|
|||||||
ExamCollectionBulkAddGroupsForm,
|
ExamCollectionBulkAddGroupsForm,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
from .models import (
|
from .models import (
|
||||||
CidUser,
|
CidUser,
|
||||||
CidUserExam,
|
CidUserExam,
|
||||||
@@ -6656,18 +6658,7 @@ def exam_search_widget(request):
|
|||||||
# Support wildcard queries
|
# Support wildcard queries
|
||||||
q = q_raw
|
q = q_raw
|
||||||
|
|
||||||
model = None
|
model = apps.get_model(model_label)
|
||||||
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
|
|
||||||
|
|
||||||
# Helper to parse optional boolean GET params
|
# Helper to parse optional boolean GET params
|
||||||
def _get_bool_param(name):
|
def _get_bool_param(name):
|
||||||
@@ -6690,64 +6681,11 @@ def exam_search_widget(request):
|
|||||||
|
|
||||||
# Build queryset
|
# Build queryset
|
||||||
qs = None
|
qs = None
|
||||||
if model is not None:
|
field_lookups = ["name__icontains"]
|
||||||
field_lookups = ["name__icontains"]
|
for lookup in field_lookups:
|
||||||
for lookup in field_lookups:
|
qs = model.objects.filter(**{lookup: q})
|
||||||
qs = model.objects.filter(**{lookup: q})
|
if qs.exists():
|
||||||
if qs.exists():
|
|
||||||
break
|
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)
|
logger.error(qs)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user