diff --git a/django_select2/forms.py b/django_select2/forms.py index 2a88c215..98079386 100644 --- a/django_select2/forms.py +++ b/django_select2/forms.py @@ -76,9 +76,16 @@ class Select2Mixin: empty_label = "" + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.i18n_name = SELECT2_TRANSLATIONS.get(get_language()) + def build_attrs(self, base_attrs, extra_attrs=None): """Add select2 data attributes.""" - default_attrs = {"data-minimum-input-length": 0} + default_attrs = { + "lang": self.i18n_name, + "data-minimum-input-length": 0, + } if self.is_required: default_attrs["data-allow-clear"] = "false" else: @@ -100,32 +107,28 @@ def optgroups(self, name, value, attrs=None): self.choices = list(chain([("", "")], self.choices)) return super().optgroups(name, value, attrs=attrs) - def _get_media(self): + @property + def media(self): """ Construct Media as a dynamic property. .. Note:: For more information visit https://docs.djangoproject.com/en/stable/topics/forms/media/#media-as-a-dynamic-property """ - lang = get_language() select2_js = (settings.SELECT2_JS,) if settings.SELECT2_JS else () select2_css = (settings.SELECT2_CSS,) if settings.SELECT2_CSS else () - i18n_name = SELECT2_TRANSLATIONS.get(lang) - if i18n_name not in settings.SELECT2_I18N_AVAILABLE_LANGUAGES: - i18n_name = None - - i18n_file = ( - ("%s/%s.js" % (settings.SELECT2_I18N_PATH, i18n_name),) if i18n_name else () - ) + i18n_file = () + if self.i18n_name in settings.SELECT2_I18N_AVAILABLE_LANGUAGES: + i18n_file = ( + ("%s/%s.js" % (settings.SELECT2_I18N_PATH, self.i18n_name),) + ) return forms.Media( js=select2_js + i18n_file + ("django_select2/django_select2.js",), css={"screen": select2_css + ("django_select2/django_select2.css",)}, ) - media = property(_get_media) - class Select2TagMixin: """Mixin to add select2 tag functionality.""" @@ -212,11 +215,7 @@ def __init__(self, attrs=None, choices=(), **kwargs): Value is a name of a field in a model (used in `queryset`). """ - self.choices = choices - if attrs is not None: - self.attrs = attrs.copy() - else: - self.attrs = {} + super().__init__(attrs, choices) self.uuid = str(uuid.uuid4()) self.field_id = signing.dumps(self.uuid) diff --git a/tests/test_forms.py b/tests/test_forms.py index 9487e428..af988845 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -3,6 +3,7 @@ from collections.abc import Iterable import pytest +from django.contrib.admin.widgets import SELECT2_TRANSLATIONS from django.db.models import QuerySet from django.urls import reverse from django.utils import translation @@ -46,6 +47,12 @@ def test_initial_form_class(self): assert "my-class" in widget.render("name", None) assert "django-select2" in widget.render("name", None) + @pytest.mark.parametrize("code,name", SELECT2_TRANSLATIONS.items()) + def test_lang_attr(self, code, name): + translation.activate(code) + widget = self.widget_cls() + assert f'lang="{name}"' in widget.render("name", None) + def test_allow_clear(self, db): required_field = self.form.fields["artist"] assert required_field.required is True @@ -219,6 +226,12 @@ def test_initial_form_class(self): "name", None ) + @pytest.mark.parametrize("code,name", SELECT2_TRANSLATIONS.items()) + def test_lang_attr(self, code, name): + translation.activate(code) + widget = self.widget_cls(data_view="heavy_data_1") + assert f'lang="{name}"' in widget.render("name", None) + def test_selected_option(self, db): not_required_field = self.form.fields["primary_genre"] assert not_required_field.required is False diff --git a/tests/testapp/settings.py b/tests/testapp/settings.py index b5ded121..f46d128d 100644 --- a/tests/testapp/settings.py +++ b/tests/testapp/settings.py @@ -25,6 +25,7 @@ ("de", "German"), ("en", "English"), ] +LANGUAGE_CODE = "en" TEMPLATES = [ {