Enhance import preview and backend handling for M2M relationships, adding sources to schema and improving missing values mapping for better template rendering and debugging.
This commit is contained in:
@@ -54,86 +54,94 @@
|
|||||||
<div class="small text-info">Would create: {{ item.missing_map.Finding|join:", " }}</div>
|
<div class="small text-info">Would create: {{ item.missing_map.Finding|join:", " }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Structure -->
|
<!-- Structure -->
|
||||||
<div class="m2m-group" data-model="Structure"><strong>Structure:</strong>
|
<div class="m2m-group" data-model="Structure"><strong>Structure:</strong>
|
||||||
{% if item.resolved_m2m.structure %}
|
{% if item.resolved_m2m.structure %}
|
||||||
{% for val in item.resolved_m2m.structure %}
|
{% for val in item.resolved_m2m.structure %}
|
||||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Structure" data-value="{{ val }}">{{ val }}</button>
|
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Structure" data-value="{{ val }}">{{ val }}</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if item.missing_map.Structure %}
|
{% if item.missing_map.Structure %}
|
||||||
{% for val in item.missing_map.Structure %}
|
{% for val in item.missing_map.Structure %}
|
||||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Structure" data-value="{{ val }}">{{ val }}</button>
|
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Structure" data-value="{{ val }}">{{ val }}</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
||||||
{% if item.missing_map.Structure %}
|
{% if item.missing_map.Structure %}
|
||||||
<div class="small text-info">Would create: {{ item.missing_map.Structure|join:", " }}</div>
|
<div class="small text-info">Would create: {{ item.missing_map.Structure|join:", " }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Condition -->
|
<!-- Condition -->
|
||||||
<div class="m2m-group" data-model="Condition"><strong>Condition:</strong>
|
<div class="m2m-group" data-model="Condition"><strong>Condition:</strong>
|
||||||
{% if item.resolved_m2m.condition %}
|
{% if item.resolved_m2m.condition %}
|
||||||
{% for val in item.resolved_m2m.condition %}
|
{% for val in item.resolved_m2m.condition %}
|
||||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Condition" data-value="{{ val }}">{{ val }}</button>
|
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Condition" data-value="{{ val }}">{{ val }}</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if item.missing_map.Condition %}
|
{% if item.missing_map.Condition %}
|
||||||
{% for val in item.missing_map.Condition %}
|
{% for val in item.missing_map.Condition %}
|
||||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Condition" data-value="{{ val }}">{{ val }}</button>
|
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Condition" data-value="{{ val }}">{{ val }}</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
||||||
{% if item.missing_map.Condition %}
|
{% if item.missing_map.Condition %}
|
||||||
<div class="small text-info">Would create: {{ item.missing_map.Condition|join:", " }}</div>
|
<div class="small text-info">Would create: {{ item.missing_map.Condition|join:", " }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Presentation -->
|
<!-- Presentation -->
|
||||||
<div class="m2m-group" data-model="Presentation"><strong>Presentation:</strong>
|
<div class="m2m-group" data-model="Presentation"><strong>Presentation:</strong>
|
||||||
{% if item.resolved_m2m.presentation %}
|
{% if item.resolved_m2m.presentation %}
|
||||||
{% for val in item.resolved_m2m.presentation %}
|
{% for val in item.resolved_m2m.presentation %}
|
||||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Presentation" data-value="{{ val }}">{{ val }}</button>
|
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Presentation" data-value="{{ val }}">{{ val }}</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if item.missing_map.Presentation %}
|
{% if item.missing_map.Presentation %}
|
||||||
{% for val in item.missing_map.Presentation %}
|
{% for val in item.missing_map.Presentation %}
|
||||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Presentation" data-value="{{ val }}">{{ val }}</button>
|
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Presentation" data-value="{{ val }}">{{ val }}</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
||||||
{% if item.missing_map.Presentation %}
|
{% if item.missing_map.Presentation %}
|
||||||
<div class="small text-info">Would create: {{ item.missing_map.Presentation|join:", " }}</div>
|
<div class="small text-info">Would create: {{ item.missing_map.Presentation|join:", " }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Subspecialty -->
|
<!-- Subspecialty -->
|
||||||
<div class="m2m-group" data-model="Subspecialty"><strong>Subspecialty:</strong>
|
<div class="m2m-group" data-model="Subspecialty"><strong>Subspecialty:</strong>
|
||||||
{% if item.resolved_m2m.subspecialty %}
|
{% if item.resolved_m2m.subspecialty %}
|
||||||
{% for val in item.resolved_m2m.subspecialty %}
|
{% for val in item.resolved_m2m.subspecialty %}
|
||||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Subspecialty" data-value="{{ val }}">{{ val }}</button>
|
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Subspecialty" data-value="{{ val }}">{{ val }}</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if item.missing_map.Subspecialty %}
|
{% if item.missing_map.Subspecialty %}
|
||||||
{% for val in item.missing_map.Subspecialty %}
|
{% for val in item.missing_map.Subspecialty %}
|
||||||
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Subspecialty" data-value="{{ val }}">{{ val }}</button>
|
<button type="button" class="m2m-toggle btn btn-sm btn-success ms-1" data-idx="{{ item.index }}" data-model="Subspecialty" data-value="{{ val }}">{{ val }}</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
<span class="text-muted m2m-none" style="display:none">(none)</span>
|
||||||
{% if item.missing_map.Subspecialty %}
|
{% if item.missing_map.Subspecialty %}
|
||||||
<div class="small text-info">Would create: {{ item.missing_map.Subspecialty|join:", " }}</div>
|
<div class="small text-info">Would create: {{ item.missing_map.Subspecialty|join:", " }}</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<label><input type="checkbox" name="selected" value="{{ item.index }}" checked> Include</label>
|
|
||||||
</div>
|
|
||||||
<!-- container for hidden exclude inputs for this item -->
|
|
||||||
<div id="exclude-container-{{ item.index }}"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- DEBUG: show raw resolved and missing maps for troubleshooting -->
|
||||||
|
<div class="card-footer text-monospace small">
|
||||||
|
<details>
|
||||||
|
<summary>Debug: resolved_m2m / missing_map (click to expand)</summary>
|
||||||
|
<pre style="white-space:pre-wrap;">resolved_m2m: {{ item.resolved_m2m|default:"{}" }}
|
||||||
|
missing_map: {{ item.missing_map|default:"{}" }}</pre>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label><input type="checkbox" name="selected" value="{{ item.index }}" checked> Include</label>
|
||||||
|
</div>
|
||||||
|
<!-- container for hidden exclude inputs for this item -->
|
||||||
|
<div id="exclude-container-{{ item.index }}"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
|||||||
+20
-1
@@ -535,6 +535,7 @@ def import_llm_questions(request):
|
|||||||
"condition": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "string"}]}, "uniqueItems": True},
|
"condition": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "string"}]}, "uniqueItems": True},
|
||||||
"presentation": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "string"}]}, "uniqueItems": True},
|
"presentation": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "string"}]}, "uniqueItems": True},
|
||||||
"subspecialty": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "string"}]}, "uniqueItems": True},
|
"subspecialty": {"type": "array", "items": {"oneOf": [{"type": "integer"}, {"type": "string"}]}, "uniqueItems": True},
|
||||||
|
"sources": {"type": "array", "items": {"type": "string"}},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -685,11 +686,29 @@ def import_llm_questions(request):
|
|||||||
|
|
||||||
m2m_map[key] = {"resolved": resolved, "missing": missing}
|
m2m_map[key] = {"resolved": resolved, "missing": missing}
|
||||||
item_report["resolved_m2m"][key] = [o.name for o in resolved]
|
item_report["resolved_m2m"][key] = [o.name for o in resolved]
|
||||||
|
# Always include an entry for this M2M (values may be empty)
|
||||||
|
item_report["missing_m2m"].append({"model": model_cls.__name__, "values": missing})
|
||||||
if missing:
|
if missing:
|
||||||
item_report["missing_m2m"].extend([{"model": model_cls.__name__, "values": missing}])
|
|
||||||
for v in missing:
|
for v in missing:
|
||||||
aggregated_would_create[model_cls.__name__].add(v)
|
aggregated_would_create[model_cls.__name__].add(v)
|
||||||
|
|
||||||
|
# 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
|
||||||
|
item_report["missing_map"] = missing_map
|
||||||
|
|
||||||
|
# Debug: log missing_map and resolved_m2m for troubleshooting
|
||||||
|
logger.debug(
|
||||||
|
"import_llm_questions: item %s missing_map_keys=%s resolved_keys=%s",
|
||||||
|
idx,
|
||||||
|
list(missing_map.keys()),
|
||||||
|
list((item_report.get("resolved_m2m") or {}).keys()),
|
||||||
|
)
|
||||||
|
|
||||||
# If dry-run, do not save; just report what would happen
|
# If dry-run, do not save; just report what would happen
|
||||||
if dry_run:
|
if dry_run:
|
||||||
item_report["status"] = "would_create"
|
item_report["status"] = "would_create"
|
||||||
|
|||||||
Reference in New Issue
Block a user