Repository: django-import-export/django-import-export

Issue:
Badly named `id` field causes UI crash
**Describe the bug**

If the `id` field is named incorrectly, then the import process will crash with `FieldError`:

![Screenshot 2023-12-20 at 15 23 10](https://github.com/django-import-export/django-import-export/assets/6249838/0e9b1878-08ad-47ee-b56d-72b64592eb01)

**To Reproduce**

- Edit the file `tests/core/exports/books.csv`
- change 'id' to 'idx'
- import the file via the admin ui


**Versions (please complete the following information):**
 - Django Import Export: 4.0.0-beta
 - Python 3.11
 - Django 5.0

**Expected behavior**

It would be best if a formatted error message was presented to the user, instead of a crash screen.




Discussion:

Resolving patch:
diff --git a/import_export/admin.py b/import_export/admin.py
--- a/import_export/admin.py
+++ b/import_export/admin.py
@@ -18,6 +18,7 @@
 from django.utils.translation import gettext_lazy as _
 from django.views.decorators.http import require_POST
 
+from .exceptions import FieldError
 from .forms import ConfirmImportForm, ImportForm, SelectableFieldsExportForm
 from .mixins import BaseExportMixin, BaseImportMixin
 from .results import RowResult
@@ -502,21 +503,27 @@ def import_action(self, request, *args, **kwargs):
                     imp_kwargs = self.get_import_data_kwargs(
                         request, *args, form=import_form, **kwargs
                     )
-                    result = resource.import_data(
-                        dataset,
-                        dry_run=True,
-                        raise_errors=False,
-                        file_name=import_file.name,
-                        user=request.user,
-                        **imp_kwargs,
-                    )
+                    try:
+                        result = resource.import_data(
+                            dataset,
+                            dry_run=True,
+                            raise_errors=False,
+                            file_name=import_file.name,
+                            user=request.user,
+                            **imp_kwargs,
+                        )
+                        context["result"] = result
 
-                    context["result"] = result
+                        if (
+                            not result.has_errors()
+                            and not result.has_validation_errors()
+                        ):
+                            context["confirm_form"] = self.create_confirm_form(
+                                request, import_form=import_form
+                            )
+                    except FieldError as e:
+                        messages.error(request, str(e))
 
-                    if not result.has_errors() and not result.has_validation_errors():
-                        context["confirm_form"] = self.create_confirm_form(
-                            request, import_form=import_form
-                        )
         else:
             res_kwargs = self.get_import_resource_kwargs(
                 request, form=import_form, **kwargs


Test patch:
diff --git a/tests/core/tests/admin_integration/test_import.py b/tests/core/tests/admin_integration/test_import.py
--- a/tests/core/tests/admin_integration/test_import.py
+++ b/tests/core/tests/admin_integration/test_import.py
@@ -19,6 +19,7 @@
 from django.utils.translation import gettext_lazy as _
 
 from import_export.admin import ExportMixin
+from import_export.exceptions import FieldError
 from import_export.formats import base_formats
 from import_export.formats.base_formats import XLSX
 from import_export.resources import ModelResource
@@ -202,6 +203,17 @@ def test_import_action_handles_ValueError_as_form_error(self):
         else:
             self.assertFormError(response, "form", "import_file", target_msg)
 
+    def test_import_action_handles_FieldError(self):
+        # issue 1722
+        with mock.patch(
+            "import_export.resources.Resource._check_import_id_fields"
+        ) as mock_check_import_id_fields:
+            mock_check_import_id_fields.side_effect = FieldError("some unknown error")
+            response = self._do_import_post(self.book_import_url, "books.csv")
+        self.assertEqual(response.status_code, 200)
+        target_msg = "Some unknown error"
+        self.assertIn(target_msg, str(response.content))
+
     @override_settings(LANGUAGE_CODE="es")
     def test_import_action_handles_ValueError_as_form_error_with_translation(self):
         with mock.patch(
diff --git a/tests/core/tests/test_admin_integration.py b/tests/core/tests/test_admin_integration.py
deleted file mode 100644