Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixes #19763 - LocaleMiddleware should check for supported languages …

…in settings.LANGUAGE_CODE
  • Loading branch information...
commit 8c8f94fe9dcdd4983ebeb59951e6f7399bc287a2 1 parent 99edbe0
@ambv ambv authored
View
1  AUTHORS
@@ -328,6 +328,7 @@ answer newbie questions, and generally made Django that much better:
Denis Kuzmichyov <kuzmichyov@gmail.com>
Panos Laganakos <panos.laganakos@gmail.com>
Nick Lane <nick.lane.au@gmail.com>
+ Łukasz Langa <lukasz@langa.pl>
Stuart Langridge <http://www.kryogenix.org/>
Paul Lanier <planier@google.com>
David Larlet <http://david.larlet.fr>
View
14 django/utils/translation/__init__.py
@@ -187,10 +187,10 @@ def get_language_info(lang_code):
try:
return LANG_INFO[lang_code]
except KeyError:
- if '-' in lang_code:
- splited_lang_code = lang_code.split('-')[0]
- try:
- return LANG_INFO[splited_lang_code]
- except KeyError:
- raise KeyError("Unknown language code %s and %s." % (lang_code, splited_lang_code))
- raise KeyError("Unknown language code %s." % lang_code)
+ if '-' not in lang_code:
+ raise KeyError("Unknown language code %s." % lang_code)
+ generic_lang_code = lang_code.split('-')[0]
+ try:
+ return LANG_INFO[generic_lang_code]
+ except KeyError:
+ raise KeyError("Unknown language code %s and %s." % (lang_code, generic_lang_code))
View
28 django/utils/translation/trans_real.py
@@ -356,6 +356,20 @@ def check_for_language(lang_code):
return True
return False
+def get_supported_language_variant(lang_code, supported=None):
+ """
+ Returns the language-code that's listed in supported languages, possibly
+ selecting a more generic variant. Raises LookupError if nothing found.
+ """
+ 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
+ raise LookupError(lang_code)
+
def get_language_from_path(path, supported=None):
"""
Returns the language-code if there is a valid language-code
@@ -396,11 +410,10 @@ def get_language_from_request(request, check_path=False):
lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)
- 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
+ try:
+ return get_supported_language_variant(lang_code, supported)
+ except LookupError:
+ pass
accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
for accept_lang, unused in parse_accept_lang_header(accept):
@@ -434,7 +447,10 @@ def get_language_from_request(request, check_path=False):
_accepted[normalized] = lang
return lang
- return settings.LANGUAGE_CODE
+ try:
+ return get_supported_language_variant(settings.LANGUAGE_CODE, supported)
+ except LookupError:
+ return settings.LANGUAGE_CODE
dot_re = re.compile(r'\S')
def blankout(src, char):
View
10 tests/regressiontests/i18n/patterns/tests.py
@@ -19,7 +19,7 @@
TEMPLATE_DIRS=(
os.path.join(os.path.dirname(upath(__file__)), 'templates'),
),
- LANGUAGE_CODE='en',
+ LANGUAGE_CODE='en-us',
LANGUAGES=(
('nl', 'Dutch'),
('en', 'English'),
@@ -171,6 +171,14 @@ def test_pt_br_redirect(self):
response = self.client.get(response['location'])
self.assertEqual(response.status_code, 200)
+ def test_pl_pl_redirect(self):
+ # language from outside of the supported LANGUAGES list
+ response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='pl-pl')
+ self.assertRedirects(response, '/en/account/register/')
+
+ response = self.client.get(response['location'])
+ self.assertEqual(response.status_code, 200)
+
class URLVaryAcceptLanguageTests(URLTestCaseBase):
"""
View
4 tests/regressiontests/i18n/tests.py
@@ -958,7 +958,7 @@ def test_localized_language_info(self):
self.assertEqual(li['bidi'], False)
def test_unknown_language_code(self):
- six.assertRaisesRegex(self, KeyError, "Unknown language code '?xx'?.", get_language_info, 'xx-xx')
+ six.assertRaisesRegex(self, KeyError, r"Unknown language code xx\.", get_language_info, 'xx')
def test_unknown_only_country_code(self):
li = get_language_info('de-xx')
@@ -968,7 +968,7 @@ def test_unknown_only_country_code(self):
self.assertEqual(li['bidi'], False)
def test_unknown_language_code_and_country_code(self):
- six.assertRaisesRegex(self, KeyError, "Unknown language code '?xx-xx'? and '?xx'?.", get_language_info, 'xx-xx')
+ six.assertRaisesRegex(self, KeyError, r"Unknown language code xx-xx and xx\.", get_language_info, 'xx-xx')
class MultipleLocaleActivationTests(TestCase):
Please sign in to comment.
Something went wrong with that request. Please try again.