Commit cac7b445 authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

Merge pull request #1100 from ambv/issue19919

Fixed #19919: get_language_from_request() disregards en-us and en
parents 90f1170b 92ebb29c
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -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)
+39 −1
Original line number Diff line number Diff line
@@ -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)