Fixes #19919: get_language_from_request() disregards "en-us" and "en" languages
when matching Accept-Language
This commit is contained in:
parent
90f1170bb9
commit
92ebb29c53
|
@ -364,10 +364,14 @@ def get_supported_language_variant(lang_code, supported=None):
|
|||
if supported is None:
|
||||
from django.conf import settings
|
||||
supported = dict(settings.LANGUAGES)
|
||||
if lang_code and lang_code not in supported:
|
||||
lang_code = lang_code.split('-')[0] # e.g. if fr-ca is not supported fallback to fr
|
||||
if lang_code and lang_code in supported and check_for_language(lang_code):
|
||||
return lang_code
|
||||
if lang_code:
|
||||
# e.g. if fr-CA is not supported, try fr-ca;
|
||||
# if that fails, fallback to fr.
|
||||
variants = (lang_code, lang_code.lower(), lang_code.split('-')[0],
|
||||
lang_code.lower().split('-')[0])
|
||||
for code in variants:
|
||||
if code in supported and check_for_language(code):
|
||||
return code
|
||||
raise LookupError(lang_code)
|
||||
|
||||
def get_language_from_path(path, supported=None):
|
||||
|
@ -438,14 +442,13 @@ def get_language_from_request(request, check_path=False):
|
|||
# need to check again.
|
||||
return _accepted[normalized]
|
||||
|
||||
for lang, dirname in ((accept_lang, normalized),
|
||||
(accept_lang.split('-')[0], normalized.split('_')[0])):
|
||||
if lang.lower() not in supported:
|
||||
try:
|
||||
accept_lang = get_supported_language_variant(accept_lang, supported)
|
||||
except LookupError:
|
||||
continue
|
||||
for path in all_locale_paths():
|
||||
if os.path.exists(os.path.join(path, dirname, 'LC_MESSAGES', 'django.mo')):
|
||||
_accepted[normalized] = lang
|
||||
return lang
|
||||
else:
|
||||
_accepted[normalized] = accept_lang
|
||||
return accept_lang
|
||||
|
||||
try:
|
||||
return get_supported_language_variant(settings.LANGUAGE_CODE, supported)
|
||||
|
|
|
@ -30,7 +30,8 @@ from django.utils.translation import (activate, deactivate,
|
|||
ngettext, ngettext_lazy,
|
||||
ungettext, ungettext_lazy,
|
||||
pgettext, pgettext_lazy,
|
||||
npgettext, npgettext_lazy)
|
||||
npgettext, npgettext_lazy,
|
||||
check_for_language)
|
||||
|
||||
from .commands.tests import can_run_extraction_tests, can_run_compilation_tests
|
||||
if can_run_extraction_tests:
|
||||
|
@ -1114,3 +1115,40 @@ class LocaleMiddlewareTests(TestCase):
|
|||
self.assertContains(response, "Oui/Non")
|
||||
response = self.client.get('/en/streaming/')
|
||||
self.assertContains(response, "Yes/No")
|
||||
|
||||
@override_settings(
|
||||
USE_I18N=True,
|
||||
LANGUAGES=(
|
||||
('bg', 'Bulgarian'),
|
||||
('en-us', 'English'),
|
||||
),
|
||||
MIDDLEWARE_CLASSES=(
|
||||
'django.middleware.locale.LocaleMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
),
|
||||
)
|
||||
class CountrySpecificLanguageTests(TestCase):
|
||||
|
||||
urls = 'i18n.urls'
|
||||
|
||||
def setUp(self):
|
||||
trans_real._accepted = {}
|
||||
self.rf = RequestFactory()
|
||||
|
||||
def test_check_for_language(self):
|
||||
self.assertTrue(check_for_language('en'))
|
||||
self.assertTrue(check_for_language('en-us'))
|
||||
self.assertTrue(check_for_language('en-US'))
|
||||
|
||||
|
||||
def test_get_language_from_request(self):
|
||||
r = self.rf.get('/')
|
||||
r.COOKIES = {}
|
||||
r.META = {'HTTP_ACCEPT_LANGUAGE': 'en-US,en;q=0.8,bg;q=0.6,ru;q=0.4'}
|
||||
lang = get_language_from_request(r)
|
||||
self.assertEqual('en-us', lang)
|
||||
r = self.rf.get('/')
|
||||
r.COOKIES = {}
|
||||
r.META = {'HTTP_ACCEPT_LANGUAGE': 'bg-bg,en-US;q=0.8,en;q=0.6,ru;q=0.4'}
|
||||
lang = get_language_from_request(r)
|
||||
self.assertEqual('bg', lang)
|
||||
|
|
Loading…
Reference in New Issue