Skip to content

Commit 9e3d9b6

Browse files
Drop official support for EOL Python and Django versions (#313)
* Drop Django < 4.2 LTS support * Drop Django 5.0 support * Drop Python < 3.10 support * Update CI node version to lts/* --------- Co-authored-by: Johannes Maron <johannes@maron.family>
1 parent d8f5b33 commit 9e3d9b6

File tree

8 files changed

+15
-69
lines changed

8 files changed

+15
-69
lines changed

Diff for: .github/workflows/ci.yml

+4-5
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
- uses: actions/checkout@v4
4545
- uses: actions/setup-node@v4
4646
with:
47-
node-version: '12.x'
47+
node-version-file: '.nvmrc'
4848
- run: npm install -g standard
4949
- run: standard
5050

@@ -66,14 +66,13 @@ jobs:
6666
strategy:
6767
matrix:
6868
python-version:
69-
- "3.8"
70-
- "3.9"
7169
- "3.10"
7270
- "3.11"
71+
- "3.12"
72+
- "3.13"
7373
django-version:
74-
- "3.2"
75-
- "4.1"
7674
- "4.2"
75+
- "5.1"
7776
runs-on: ubuntu-latest
7877
steps:
7978
- uses: actions/checkout@v4

Diff for: .nvmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
lts/*

Diff for: django_select2/forms.py

+3-16
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@
6060
from itertools import chain
6161
from pickle import PicklingError # nosec
6262

63-
import django
6463
from django import forms
64+
from django.contrib.admin.utils import lookup_spawns_duplicates
6565
from django.contrib.admin.widgets import AutocompleteMixin
6666
from django.core import signing
6767
from django.db.models import Q
@@ -71,13 +71,6 @@
7171
from .cache import cache
7272
from .conf import settings
7373

74-
if django.VERSION < (4, 0):
75-
from django.contrib.admin.utils import (
76-
lookup_needs_distinct as lookup_spawns_duplicates,
77-
)
78-
else:
79-
from django.contrib.admin.utils import lookup_spawns_duplicates
80-
8174

8275
class Select2Mixin:
8376
"""
@@ -96,15 +89,9 @@ class Select2Mixin:
9689
@property
9790
def i18n_name(self):
9891
"""Name of the i18n file for the current language."""
99-
if django.VERSION < (4, 1):
100-
from django.contrib.admin.widgets import SELECT2_TRANSLATIONS
101-
from django.utils.translation import get_language
102-
103-
return SELECT2_TRANSLATIONS.get(get_language())
104-
else:
105-
from django.contrib.admin.widgets import get_select2_language
92+
from django.contrib.admin.widgets import get_select2_language
10693

107-
return get_select2_language()
94+
return get_select2_language()
10895

10996
def build_attrs(self, base_attrs, extra_attrs=None):
11097
"""Add select2 data attributes."""

Diff for: example/example/settings.py

-2
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,6 @@
105105

106106
USE_I18N = True
107107

108-
USE_L10N = True
109-
110108
USE_TZ = True
111109

112110

Diff for: pyproject.toml

+5-6
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,18 @@ classifiers = [
2020
"Programming Language :: Python",
2121
"Programming Language :: Python :: 3",
2222
"Programming Language :: Python :: 3 :: Only",
23-
"Programming Language :: Python :: 3.8",
24-
"Programming Language :: Python :: 3.9",
2523
"Programming Language :: Python :: 3.10",
2624
"Programming Language :: Python :: 3.11",
25+
"Programming Language :: Python :: 3.12",
26+
"Programming Language :: Python :: 3.13",
2727
"Framework :: Django",
28-
"Framework :: Django :: 3.2",
29-
"Framework :: Django :: 4.1",
3028
"Framework :: Django :: 4.2",
29+
"Framework :: Django :: 5.1",
3130
"Topic :: Software Development",
3231
]
33-
requires-python = ">=3.8"
32+
requires-python = ">=3.10"
3433
dependencies = [
35-
"django>=3.2",
34+
"django>=4.2",
3635
"django-appconf>=0.6.0"
3736
]
3837

Diff for: tests/test_forms.py

+1-31
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import os
33
from collections.abc import Iterable
44

5-
import django
65
import pytest
76
from django.db.models import QuerySet
87
from django.urls import reverse
@@ -751,7 +750,7 @@ def test_widgets_selected_after_validation_error(
751750
assert len(city_names_from_browser) != City.objects.count()
752751
assert city_names_from_browser == city_names_from_db
753752

754-
# selecting a city reaaly does it
753+
# selecting a city really does it
755754
city_option = driver.find_element(
756755
By.CSS_SELECTOR, ".select2-results li:nth-child(2)"
757756
)
@@ -851,7 +850,6 @@ def widget_fixture(request):
851850
return widget_class(**widget_kwargs)
852851

853852

854-
@pytest.mark.skipif(django.VERSION < (4, 1), reason="Only for Django 4.1+")
855853
@pytest.mark.parametrize(
856854
"locale,expected",
857855
[
@@ -868,38 +866,10 @@ def test_i18n_name_property_with_country_code_in_locale(widget, locale, expected
868866
assert widget.i18n_name == expected
869867

870868

871-
@pytest.mark.skipif(django.VERSION < (4, 1), reason="Only for Django 4.1+")
872869
def test_i18n_media_js_with_country_code_in_locale(widget):
873870
translation.activate("fr-FR")
874871
assert tuple(widget.media._js) == (
875872
"admin/js/vendor/select2/select2.full.min.js",
876873
"admin/js/vendor/select2/i18n/fr.js",
877874
"django_select2/django_select2.js",
878875
)
879-
880-
881-
@pytest.mark.skipif(django.VERSION >= (4, 1), reason="Only for Django 4.0 and previous")
882-
@pytest.mark.parametrize(
883-
"locale,expected",
884-
[
885-
("fr-FR", None),
886-
# Some locales with a country code are natively supported by select2's i18n
887-
("pt-BR", "pt-BR"),
888-
("sr-Cyrl", "sr-Cyrl"),
889-
],
890-
)
891-
def test_i18n_name_property_with_country_code_in_locale_for_older_django(
892-
widget, locale, expected
893-
):
894-
"""No fallback for locale with an unsupported country code."""
895-
with translation.override(locale):
896-
assert widget.i18n_name == expected
897-
898-
899-
@pytest.mark.skipif(django.VERSION >= (4, 1), reason="Only for Django 4.0 and previous")
900-
def test_i18n_media_js_with_country_code_in_locale_for_older_django(widget):
901-
translation.activate("fr-FR")
902-
assert tuple(widget.media._js) == (
903-
"admin/js/vendor/select2/select2.full.min.js",
904-
"django_select2/django_select2.js",
905-
)

Diff for: tests/test_views.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22

3+
from django.urls import reverse
34
from django.utils.encoding import smart_str
45

56
from django_select2.cache import cache
@@ -11,11 +12,6 @@
1112
)
1213
from tests.testapp.models import Genre
1314

14-
try:
15-
from django.urls import reverse
16-
except ImportError:
17-
from django.core.urlresolvers import reverse
18-
1915

2016
class TestAutoResponseView:
2117
def test_get(self, client, artists):

Diff for: tests/testapp/settings.py

-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import os.path
22

3-
import django
4-
53
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
64
DEBUG = True
75

@@ -40,7 +38,5 @@
4038

4139
SECRET_KEY = "123456"
4240

43-
if django.VERSION < (4, 0):
44-
USE_L10N = True
4541
USE_I18N = True
4642
USE_TZ = True

0 commit comments

Comments
 (0)