{% for source in item.payload.sources %}
@@ -56,14 +56,14 @@
{% endfor %}
{% endif %}
- {% if item.missing_map.Finding %}
- {% for val in item.missing_map.Finding %}
+ {% if item.missing_map.finding %}
+ {% for val in item.missing_map.finding %}
{% endfor %}
{% endif %}
(none)
- {% if item.missing_map.Finding %}
-
Would create: {{ item.missing_map.Finding|join:", " }}
+ {% if item.missing_map.finding %}
+
Would create: {{ item.missing_map.finding|join:", " }}
{% endif %}
@@ -75,14 +75,14 @@
{% endfor %}
{% endif %}
- {% if item.missing_map.Structure %}
- {% for val in item.missing_map.Structure %}
+ {% if item.missing_map.structure %}
+ {% for val in item.missing_map.structure %}
{% endfor %}
{% endif %}
(none)
- {% if item.missing_map.Structure %}
-
Would create: {{ item.missing_map.Structure|join:", " }}
+ {% if item.missing_map.structure %}
+
Would create: {{ item.missing_map.structure|join:", " }}
{% endif %}
@@ -93,14 +93,14 @@
{% endfor %}
{% endif %}
- {% if item.missing_map.Condition %}
- {% for val in item.missing_map.Condition %}
+ {% if item.missing_map.condition %}
+ {% for val in item.missing_map.condition %}
{% endfor %}
{% endif %}
(none)
- {% if item.missing_map.Condition %}
-
Would create: {{ item.missing_map.Condition|join:", " }}
+ {% if item.missing_map.condition %}
+
Would create: {{ item.missing_map.condition|join:", " }}
{% endif %}
@@ -111,14 +111,14 @@
{% endfor %}
{% endif %}
- {% if item.missing_map.Presentation %}
- {% for val in item.missing_map.Presentation %}
+ {% if item.missing_map.presentation %}
+ {% for val in item.missing_map.presentation %}
{% endfor %}
{% endif %}
(none)
- {% if item.missing_map.Presentation %}
-
Would create: {{ item.missing_map.Presentation|join:", " }}
+ {% if item.missing_map.presentation %}
+
Would create: {{ item.missing_map.presentation|join:", " }}
{% endif %}
@@ -129,14 +129,14 @@
{% endfor %}
{% endif %}
- {% if item.missing_map.Subspecialty %}
- {% for val in item.missing_map.Subspecialty %}
+ {% if item.missing_map.subspecialty %}
+ {% for val in item.missing_map.subspecialty %}
{% endfor %}
{% endif %}
(none)
- {% if item.missing_map.Subspecialty %}
-
Would create: {{ item.missing_map.Subspecialty|join:", " }}
+ {% if item.missing_map.subspecialty %}
+
Would create: {{ item.missing_map.subspecialty|join:", " }}
{% endif %}
diff --git a/sbas/views.py b/sbas/views.py
index 1e4c9cf9..0cd7c5a2 100644
--- a/sbas/views.py
+++ b/sbas/views.py
@@ -694,11 +694,8 @@ def import_llm_questions(request):
# Build a simple map of missing values per model (stringified) for robust template rendering
# Provide both lowercase and capitalized keys so templates referencing either form will work
- missing_map = {}
- for k, v in m2m_map.items():
- vals = [str(x) for x in v["missing"]]
- missing_map[k] = vals
- missing_map[k.capitalize()] = vals
+ # missing_map keys are lowercase (matching m2m_map keys)
+ missing_map = {k: [str(x) for x in v["missing"]] for k, v in m2m_map.items()}
item_report["missing_map"] = missing_map
# Debug: log missing_map and resolved_m2m for troubleshooting
@@ -844,6 +841,31 @@ def import_llm_confirm(request):
# perform actual import for selected indices
from atlas.models import Finding, Structure, Condition, Presentation, Subspecialty
+ # Parse exclude inputs of the form exclude_="Model:::value" (may be multiple per idx)
+ excluded_map = defaultdict(lambda: defaultdict(set))
+ for k, vlist in request.POST.lists():
+ if not k.startswith("exclude_"):
+ continue
+ try:
+ idx_str = k.split("exclude_")[1]
+ idx_key = int(idx_str)
+ except Exception:
+ continue
+ for entry in vlist:
+ # entry format: Model:::value
+ try:
+ model_name, val = entry.split(":::", 1)
+ excluded_map[idx_key][model_name].add(val)
+ except Exception:
+ continue
+ # Debug: log exclusions parsed from POST
+ try:
+ # convert sets to lists for logging
+ log_map = {i: {m: list(vals) for m, vals in models.items()} for i, models in excluded_map.items()}
+ logger.debug("import_llm_confirm: excluded_map=%s", log_map)
+ except Exception:
+ logger.exception("Failed to log excluded_map")
+
created = 0
errors = []
actually_created = defaultdict(list)
@@ -899,9 +921,18 @@ def import_llm_confirm(request):
if not qs.exists():
qs = model_cls.objects.filter(name__icontains=v)
if qs.exists():
- final_objs.extend(list(qs[:5]))
+ # add resolved objects unless excluded for this item
+ for obj in list(qs[:5]):
+ if obj.name in excluded_map.get(idx, {}).get(model_cls.__name__, set()):
+ logger.debug("Skipping resolved attach for idx=%s model=%s name=%s due to exclusion", idx, model_cls.__name__, obj.name)
+ continue
+ final_objs.append(obj)
else:
if allow_create_m2m:
+ # skip creation if excluded for this item
+ if v in excluded_map.get(idx, {}).get(model_cls.__name__, set()):
+ logger.debug("Skipping creation for idx=%s model=%s name=%s due to exclusion", idx, model_cls.__name__, v)
+ continue
obj, created_flag = model_cls.objects.get_or_create(name=v)
final_objs.append(obj)
actually_created[model_cls.__name__].append(obj.pk)