mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	Fixes #19919: get_language_from_request() disregards "en-us" and "en" languages
when matching Accept-Language
This commit is contained in:
		| @@ -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: | ||||
|                 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 | ||||
|         try: | ||||
|             accept_lang = get_supported_language_variant(accept_lang, supported) | ||||
|         except LookupError: | ||||
|             continue | ||||
|         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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user