diff --git a/web/core/views.py b/web/core/views.py index c91aef3..508fa12 100644 --- a/web/core/views.py +++ b/web/core/views.py @@ -332,10 +332,35 @@ def import_wizard(request): form = ImportForm(request.POST, request.FILES) if form.is_valid(): try: + raw = form.cleaned_data["file"].read() + + # --- header check (tolerant: utf-8-sig removes BOM, strip spaces, case-insensitive) --- + import io, csv as _csv + sio = io.StringIO(raw.decode("utf-8-sig", errors="replace")) + rdr = _csv.reader(sio) + first_row = next(rdr, []) + norm = [c.strip().lower() for c in first_row] + expected_norm = [c.lower() for c in EXPECTED_HEADERS] + + # If the first row doesn’t look like our header, allow import to proceed, + # but show a gentle warning in the result page. + header_ok = (norm == expected_norm) + + # hand off to your existing robust importer report = import_csv_bytes( - form.cleaned_data["file"].read(), + raw, dry_run=form.cleaned_data["dry_run"], ) + + # attach header check info (if your template shows report dicts) + report = report or {} + report["header_ok"] = header_ok + if not header_ok: + messages.warning( + request, + "The first row does not match the expected header; assuming the file has no header." + ) + return render( request, "import_result.html",