diff --git a/django/contrib/admin/widgets.py b/django/contrib/admin/widgets.py index b81ea7de3e..c64c5d14f3 100644 --- a/django/contrib/admin/widgets.py +++ b/django/contrib/admin/widgets.py @@ -450,6 +450,19 @@ SELECT2_TRANSLATIONS = { SELECT2_TRANSLATIONS.update({"zh-hans": "zh-CN", "zh-hant": "zh-TW"}) +def get_select2_language(): + lang_code = get_language() + supported_code = SELECT2_TRANSLATIONS.get(lang_code) + if supported_code is None: + # If 'zh-hant-tw' is not supported, try subsequent language codes i.e. + # 'zh-hant' and 'zh'. + i = None + while (i := lang_code.rfind("-", 0, i)) > -1: + if supported_code := SELECT2_TRANSLATIONS.get(lang_code[:i]): + return supported_code + return supported_code + + class AutocompleteMixin: """ Select widget mixin that loads options from AutocompleteJsonView via AJAX. @@ -466,7 +479,7 @@ class AutocompleteMixin: self.db = using self.choices = choices self.attrs = {} if attrs is None else attrs.copy() - self.i18n_name = SELECT2_TRANSLATIONS.get(get_language()) + self.i18n_name = get_select2_language() def get_url(self): return reverse(self.url_name % self.admin_site.name) diff --git a/tests/admin_widgets/test_autocomplete_widget.py b/tests/admin_widgets/test_autocomplete_widget.py index c7bcbd1d13..e2827b9147 100644 --- a/tests/admin_widgets/test_autocomplete_widget.py +++ b/tests/admin_widgets/test_autocomplete_widget.py @@ -166,6 +166,13 @@ class AutocompleteMixinTests(TestCase): ) languages = ( ("de", "de"), + # Subsequent language codes are used when the language code is not + # supported. + ("de-at", "de"), + ("de-ch-1901", "de"), + ("en-latn-us", "en"), + ("nl-nl-x-informal", "nl"), + ("zh-hans-HK", "zh-CN"), # Language with code 00 does not exist. ("00", None), # Language files are case sensitive.