Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixes #19763 - LocaleMiddleware should check for supported languages …

…in settings.LANGUAGE_CODE
  • Loading branch information...
commit 8c8f94fe9dcdd4983ebeb59951e6f7399bc287a2 1 parent 99edbe0
Łukasz Langa authored February 24, 2013
1  AUTHORS
@@ -328,6 +328,7 @@ answer newbie questions, and generally made Django that much better:
328 328
     Denis Kuzmichyov <kuzmichyov@gmail.com>
329 329
     Panos Laganakos <panos.laganakos@gmail.com>
330 330
     Nick Lane <nick.lane.au@gmail.com>
  331
+    Łukasz Langa <lukasz@langa.pl>
331 332
     Stuart Langridge <http://www.kryogenix.org/>
332 333
     Paul Lanier <planier@google.com>
333 334
     David Larlet <http://david.larlet.fr>
14  django/utils/translation/__init__.py
@@ -187,10 +187,10 @@ def get_language_info(lang_code):
187 187
     try:
188 188
         return LANG_INFO[lang_code]
189 189
     except KeyError:
190  
-        if '-' in lang_code:
191  
-            splited_lang_code = lang_code.split('-')[0]
192  
-            try:
193  
-                return LANG_INFO[splited_lang_code]
194  
-            except KeyError:
195  
-                raise KeyError("Unknown language code %s and %s." % (lang_code, splited_lang_code))
196  
-        raise KeyError("Unknown language code %s." % lang_code)
  190
+        if '-' not in lang_code:
  191
+            raise KeyError("Unknown language code %s." % lang_code)
  192
+        generic_lang_code = lang_code.split('-')[0]
  193
+        try:
  194
+            return LANG_INFO[generic_lang_code]
  195
+        except KeyError:
  196
+            raise KeyError("Unknown language code %s and %s." % (lang_code, generic_lang_code))
28  django/utils/translation/trans_real.py
@@ -356,6 +356,20 @@ def check_for_language(lang_code):
356 356
             return True
357 357
     return False
358 358
 
  359
+def get_supported_language_variant(lang_code, supported=None):
  360
+    """
  361
+    Returns the language-code that's listed in supported languages, possibly
  362
+    selecting a more generic variant. Raises LookupError if nothing found.
  363
+    """
  364
+    if supported is None:
  365
+        from django.conf import settings
  366
+        supported = dict(settings.LANGUAGES)
  367
+    if lang_code and lang_code not in supported:
  368
+        lang_code = lang_code.split('-')[0] # e.g. if fr-ca is not supported fallback to fr
  369
+    if lang_code and lang_code in supported and check_for_language(lang_code):
  370
+        return lang_code
  371
+    raise LookupError(lang_code)
  372
+
359 373
 def get_language_from_path(path, supported=None):
360 374
     """
361 375
     Returns the language-code if there is a valid language-code
@@ -396,11 +410,10 @@ def get_language_from_request(request, check_path=False):
396 410
 
397 411
     lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)
398 412
 
399  
-    if lang_code and lang_code not in supported:
400  
-        lang_code = lang_code.split('-')[0] # e.g. if fr-ca is not supported fallback to fr
401  
-
402  
-    if lang_code and lang_code in supported and check_for_language(lang_code):
403  
-        return lang_code
  413
+    try:
  414
+        return get_supported_language_variant(lang_code, supported)
  415
+    except LookupError:
  416
+        pass
404 417
 
405 418
     accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
406 419
     for accept_lang, unused in parse_accept_lang_header(accept):
@@ -434,7 +447,10 @@ def get_language_from_request(request, check_path=False):
434 447
                     _accepted[normalized] = lang
435 448
                     return lang
436 449
 
437  
-    return settings.LANGUAGE_CODE
  450
+    try:
  451
+        return get_supported_language_variant(settings.LANGUAGE_CODE, supported)
  452
+    except LookupError:
  453
+        return settings.LANGUAGE_CODE
438 454
 
439 455
 dot_re = re.compile(r'\S')
440 456
 def blankout(src, char):
10  tests/regressiontests/i18n/patterns/tests.py
@@ -19,7 +19,7 @@
19 19
     TEMPLATE_DIRS=(
20 20
         os.path.join(os.path.dirname(upath(__file__)), 'templates'),
21 21
     ),
22  
-    LANGUAGE_CODE='en',
  22
+    LANGUAGE_CODE='en-us',
23 23
     LANGUAGES=(
24 24
         ('nl', 'Dutch'),
25 25
         ('en', 'English'),
@@ -171,6 +171,14 @@ def test_pt_br_redirect(self):
171 171
         response = self.client.get(response['location'])
172 172
         self.assertEqual(response.status_code, 200)
173 173
 
  174
+    def test_pl_pl_redirect(self):
  175
+        # language from outside of the supported LANGUAGES list
  176
+        response = self.client.get('/account/register/', HTTP_ACCEPT_LANGUAGE='pl-pl')
  177
+        self.assertRedirects(response, '/en/account/register/')
  178
+
  179
+        response = self.client.get(response['location'])
  180
+        self.assertEqual(response.status_code, 200)
  181
+
174 182
 
175 183
 class URLVaryAcceptLanguageTests(URLTestCaseBase):
176 184
     """
4  tests/regressiontests/i18n/tests.py
@@ -958,7 +958,7 @@ def test_localized_language_info(self):
958 958
         self.assertEqual(li['bidi'], False)
959 959
 
960 960
     def test_unknown_language_code(self):
961  
-        six.assertRaisesRegex(self, KeyError, "Unknown language code '?xx'?.", get_language_info, 'xx-xx')
  961
+        six.assertRaisesRegex(self, KeyError, r"Unknown language code xx\.", get_language_info, 'xx')
962 962
 
963 963
     def test_unknown_only_country_code(self):
964 964
         li = get_language_info('de-xx')
@@ -968,7 +968,7 @@ def test_unknown_only_country_code(self):
968 968
         self.assertEqual(li['bidi'], False)
969 969
 
970 970
     def test_unknown_language_code_and_country_code(self):
971  
-        six.assertRaisesRegex(self, KeyError, "Unknown language code '?xx-xx'? and '?xx'?.", get_language_info, 'xx-xx')
  971
+        six.assertRaisesRegex(self, KeyError, r"Unknown language code xx-xx and xx\.", get_language_info, 'xx-xx')
972 972
 
973 973
 
974 974
 class MultipleLocaleActivationTests(TestCase):

0 notes on commit 8c8f94f

Please sign in to comment.
Something went wrong with that request. Please try again.