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

Issue:
Improve validation documentation
**Problem**

- Improved documentation around validation process.  Closes #1464
- Improved error messages raised by Widgets and added support for i18n. Closes #1421
- I also moved some images added in a previous PR to a single folder for consistency

**Acceptance Criteria**

- Manual testing
- Automated testing
- Built and reviewed docs locally


Discussion:

Resolving patch:
diff --git a/import_export/mixins.py b/import_export/mixins.py
--- a/import_export/mixins.py
+++ b/import_export/mixins.py
@@ -1,4 +1,5 @@
 import logging
+from warnings import warn
 
 from django.conf import settings
 from django.http import HttpResponse
@@ -142,6 +143,12 @@ def get_form_kwargs(self):
 
 class ExportViewFormMixin(ExportViewMixin, FormView):
     def form_valid(self, form):
+        warn(
+            "ExportViewFormMixin is deprecated and will be removed "
+            "in a future release",
+            DeprecationWarning,
+            stacklevel=2,
+        )
         formats = self.get_export_formats()
         file_format = formats[int(form.cleaned_data["file_format"])]()
         if hasattr(self, "get_filterset"):


Test patch:
diff --git a/tests/core/tests/test_mixins.py b/tests/core/tests/test_mixins.py
--- a/tests/core/tests/test_mixins.py
+++ b/tests/core/tests/test_mixins.py
@@ -1,3 +1,4 @@
+import warnings
 from unittest import mock
 from unittest.mock import MagicMock
 
@@ -34,7 +35,9 @@ def test_post(self):
         data = {
             "file_format": "0",
         }
-        response = self.client.post(self.url, data)
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            response = self.client.post(self.url, data)
         self.assertContains(response, self.cat1.name, status_code=200)
         self.assertTrue(response.has_header("Content-Disposition"))
         self.assertEqual(response["Content-Type"], "text/csv")
@@ -58,7 +61,9 @@ def get_queryset(self):
         with mock.patch("import_export.mixins.HttpResponse") as mock_http_response:
             # on first instantiation, raise TypeError, on second, return mock
             mock_http_response.side_effect = [TypeError(), mock_http_response]
-            m.form_valid(self.form)
+            with warnings.catch_warnings():
+                warnings.filterwarnings("ignore", category=DeprecationWarning)
+                m.form_valid(self.form)
             self.assertEqual(
                 content_type, mock_http_response.call_args_list[0][1]["content_type"]
             )
@@ -90,7 +95,9 @@ def get_filterset_class(self):
                 return MagicMock()
 
         m = TestMixin()
-        res = m.form_valid(self.form)
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            res = m.form_valid(self.form)
         self.assertEqual(200, res.status_code)
         self.assertEqual(1, m.mock_get_filterset_call_count)
         self.assertEqual(1, m.mock_get_filterset_class_call_count)
diff --git a/tests/core/tests/test_resources/test_resources.py b/tests/core/tests/test_resources/test_resources.py
--- a/tests/core/tests/test_resources/test_resources.py
+++ b/tests/core/tests/test_resources/test_resources.py
@@ -719,10 +719,6 @@ def test_import_data_error_saving_model(self):
         row[0] = "foo"
         self.dataset.append(row)
         result = self.resource.import_data(self.dataset, raise_errors=False)
-        if result.has_errors():
-            for row in result.rows:
-                for error in row.errors:
-                    print(str(error.error))
 
         self.assertTrue(result.has_errors())
         self.assertTrue(result.rows[0].errors)