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

Issue:
Remove support for django3.2
Django 3.2 reaches EOL on [30 April 2024](https://endoflife.date/django).

- Remove from project definition
- Remove test code which refers to code pre 4.2




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
@@ -667,8 +667,7 @@ def get_export_queryset(self, request):
             "model_admin": self,
             "sortable_by": self.sortable_by,
         }
-        if django.VERSION >= (4, 0):
-            changelist_kwargs["search_help_text"] = self.search_help_text
+        changelist_kwargs["search_help_text"] = self.search_help_text
 
         class ExportChangeList(ChangeList):
             def get_results(self, request):


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -52,9 +52,9 @@ jobs:
         -u${{ env.IMPORT_EXPORT_MYSQL_USER }}
         -p${{ env.IMPORT_EXPORT_MYSQL_PASSWORD }}
     - name: Check out repository code
-      uses: actions/checkout@v3
+      uses: actions/checkout@v4
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v4
+      uses: actions/setup-python@v5
       with:
         python-version: ${{ matrix.python-version }}
     - name: Install Dependencies
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
@@ -4,7 +4,6 @@
 from unittest import mock
 from unittest.mock import patch
 
-import django
 from core.admin import AuthorAdmin, BookAdmin, CustomBookAdmin, ImportMixin
 from core.models import Author, Book, EBook, Parent
 from core.tests.admin_integration.mixins import AdminTestMixin
@@ -162,19 +161,14 @@ def test_import_action_handles_UnicodeDecodeError_as_form_error(self):
             "'UnicodeDecodeError' encountered while trying to read file. "
             "Ensure you have chosen the correct format for the file."
         )
-        # required for testing via tox
-        # remove after django 5.0 released
-        if django.VERSION >= (4, 0):
-            with warnings.catch_warnings():
-                warnings.filterwarnings("ignore", category=DeprecationWarning)
-                try:
-                    self.assertFormError(
-                        response.context["form"], "import_file", target_msg
-                    )
-                except TypeError:
-                    self.assertFormError(response, "form", "import_file", target_msg)
-        else:
-            self.assertFormError(response, "form", "import_file", target_msg)
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            try:
+                self.assertFormError(
+                    response.context["form"], "import_file", target_msg
+                )
+            except TypeError:
+                self.assertFormError(response, "form", "import_file", target_msg)
 
     def test_import_action_handles_ValueError_as_form_error(self):
         with mock.patch(
@@ -188,19 +182,14 @@ def test_import_action_handles_ValueError_as_form_error(self):
             "Ensure you have chosen the correct format for the file."
         )
 
-        # required for testing via tox
-        # remove after django 5.0 released
-        if django.VERSION >= (4, 0):
-            with warnings.catch_warnings():
-                warnings.filterwarnings("ignore", category=DeprecationWarning)
-                try:
-                    self.assertFormError(
-                        response.context["form"], "import_file", target_msg
-                    )
-                except TypeError:
-                    self.assertFormError(response, "form", "import_file", target_msg)
-        else:
-            self.assertFormError(response, "form", "import_file", target_msg)
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            try:
+                self.assertFormError(
+                    response.context["form"], "import_file", target_msg
+                )
+            except TypeError:
+                self.assertFormError(response, "form", "import_file", target_msg)
 
     def test_import_action_handles_FieldError(self):
         # issue 1722
@@ -226,19 +215,14 @@ def test_import_action_handles_ValueError_as_form_error_with_translation(self):
             "Asegúrese que seleccionó el formato correcto para el archivo."
         )
 
-        # required for testing via tox
-        # remove after django 5.0 released
-        if django.VERSION >= (4, 0):
-            with warnings.catch_warnings():
-                warnings.filterwarnings("ignore", category=DeprecationWarning)
-                try:
-                    self.assertFormError(
-                        response.context["form"], "import_file", target_msg
-                    )
-                except TypeError:
-                    self.assertFormError(response, "form", "import_file", target_msg)
-        else:
-            self.assertFormError(response, "form", "import_file", target_msg)
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            try:
+                self.assertFormError(
+                    response.context["form"], "import_file", target_msg
+                )
+            except TypeError:
+                self.assertFormError(response, "form", "import_file", target_msg)
 
     def test_import_action_invalidates_data_sheet_with_no_headers_or_data(self):
         # GET the import form
@@ -256,19 +240,14 @@ def test_import_action_invalidates_data_sheet_with_no_headers_or_data(self):
             "has the correct headers or data for import."
         )
 
-        # required for testing via tox
-        # remove after django 5.0 released
-        if django.VERSION >= (4, 0):
-            with warnings.catch_warnings():
-                warnings.filterwarnings("ignore", category=DeprecationWarning)
-                try:
-                    self.assertFormError(
-                        response.context["form"], "import_file", target_msg
-                    )
-                except TypeError:
-                    self.assertFormError(response, "form", "import_file", target_msg)
-        else:
-            self.assertFormError(response, "form", "import_file", target_msg)
+        with warnings.catch_warnings():
+            warnings.filterwarnings("ignore", category=DeprecationWarning)
+            try:
+                self.assertFormError(
+                    response.context["form"], "import_file", target_msg
+                )
+            except TypeError:
+                self.assertFormError(response, "form", "import_file", target_msg)
 
     @ignore_widget_deprecation_warning
     def test_delete_from_admin(self):
diff --git a/tests/core/tests/test_widgets.py b/tests/core/tests/test_widgets.py
--- a/tests/core/tests/test_widgets.py
+++ b/tests/core/tests/test_widgets.py
@@ -1,7 +1,7 @@
 import json
 from datetime import date, datetime, time, timedelta
 from decimal import Decimal
-from unittest import mock, skipUnless
+from unittest import mock
 from unittest.mock import patch
 
 import django
@@ -102,17 +102,6 @@ class FormatDatetimeTest(TestCase):
     target_dt = "02.08.0010"
     format = "%d.%m.%Y"
 
-    @skipUnless(
-        django.VERSION[0] < 4, f"skipping django {django.VERSION} version specific test"
-    )
-    def test_format_datetime_lt_django4(self):
-        self.assertEqual(
-            self.target_dt, widgets.format_datetime(self.date, self.format)
-        )
-
-    @skipUnless(
-        django.VERSION[0] >= 4, f"running django {django.VERSION} version specific test"
-    )
     def test_format_datetime_gte_django4(self):
         self.assertEqual(
             self.target_dt, widgets.format_datetime(self.date, self.format)
@@ -383,17 +372,6 @@ def test_render_None_coerce_to_string_False(self):
     def test_render_invalid_type(self):
         self.assertEqual(self.widget.render("a"), "")
 
-    @skipUnless(
-        django.VERSION[0] < 4, f"skipping django {django.VERSION} version specific test"
-    )
-    @override_settings(LANGUAGE_CODE="fr-fr", USE_L10N=True)
-    def test_locale_render_coerce_to_string_lt4(self):
-        self.assertEqual("11,111", self.widget_coerce_to_string.render(self.value))
-
-    @skipUnless(
-        django.VERSION[0] >= 4,
-        f"skipping django {django.VERSION} version specific test",
-    )
     @override_settings(LANGUAGE_CODE="fr-fr")
     def test_locale_render_coerce_to_string_gte4(self):
         self.assertEqual("11,111", self.widget_coerce_to_string.render(self.value))
@@ -426,17 +404,6 @@ def test_clean_empty_string(self):
         self.assertEqual(self.widget.clean(" "), None)
         self.assertEqual(self.widget.clean("\r\n\t"), None)
 
-    @skipUnless(
-        django.VERSION[0] < 4, f"skipping django {django.VERSION} version specific test"
-    )
-    @override_settings(LANGUAGE_CODE="fr-fr", USE_L10N=True)
-    def test_locale_render_coerce_to_string_lt4(self):
-        self.assertEqual(self.widget_coerce_to_string.render(self.value), "11,111")
-
-    @skipUnless(
-        django.VERSION[0] >= 4,
-        f"skipping django {django.VERSION} version specific test",
-    )
     @override_settings(LANGUAGE_CODE="fr-fr")
     def test_locale_render_coerce_to_string_gte4(self):
         self.assertEqual(self.widget_coerce_to_string.render(self.value), "11,111")
@@ -470,17 +437,6 @@ def test_clean_empty_string(self):
         self.assertEqual(self.widget.clean(" "), None)
         self.assertEqual(self.widget.clean("\r\n\t"), None)
 
-    @skipUnless(
-        django.VERSION[0] < 4, f"skipping django {django.VERSION} version specific test"
-    )
-    @override_settings(LANGUAGE_CODE="fr-fr", USE_L10N=True)
-    def test_locale_render_coerce_to_string_lt4(self):
-        self.assertEqual(self.widget.render(self.value), "11,111")
-
-    @skipUnless(
-        django.VERSION[0] >= 4,
-        f"skipping django {django.VERSION} version specific test",
-    )
     @override_settings(LANGUAGE_CODE="fr-fr")
     def test_locale_render_coerce_to_string_gte4(self):
         self.assertEqual(self.widget.render(self.value), "11,111")
@@ -511,17 +467,6 @@ def test_clean_empty_string(self):
     def test_render_invalid_type(self):
         self.assertEqual(self.widget.render("a"), "")
 
-    @skipUnless(
-        django.VERSION[0] < 4, f"skipping django {django.VERSION} version specific test"
-    )
-    @override_settings(LANGUAGE_CODE="fr-fr", USE_L10N=True)
-    def test_locale_render_lt_django4(self):
-        self.assertEqual(self.widget_coerce_to_string.render(self.value), "0")
-
-    @skipUnless(
-        django.VERSION[0] >= 4,
-        f"skipping django {django.VERSION} version specific test",
-    )
     @override_settings(LANGUAGE_CODE="fr-fr")
     def test_locale_render_gte_django4(self):
         self.assertEqual(self.widget_coerce_to_string.render(self.value), "0")