Fixed #34069 -- Made LocaleMiddleware respect language from requests when i18n patterns are used.
This commit is contained in:
parent
004f985b91
commit
94e7f471c4
|
@ -16,28 +16,37 @@ class LocaleMiddleware(MiddlewareMixin):
|
|||
|
||||
response_redirect_class = HttpResponseRedirect
|
||||
|
||||
def get_fallback_language(self, request):
|
||||
"""
|
||||
Return the fallback language for the current request based on the
|
||||
settings. If LANGUAGE_CODE is a variant not included in the supported
|
||||
languages, get_fallback_language() will try to fallback to a supported
|
||||
generic variant.
|
||||
|
||||
Can be overridden to have a fallback language depending on the request,
|
||||
e.g. based on top level domain.
|
||||
"""
|
||||
try:
|
||||
return translation.get_supported_language_variant(settings.LANGUAGE_CODE)
|
||||
except LookupError:
|
||||
return settings.LANGUAGE_CODE
|
||||
|
||||
def process_request(self, request):
|
||||
urlconf = getattr(request, "urlconf", settings.ROOT_URLCONF)
|
||||
(
|
||||
i18n_patterns_used,
|
||||
prefixed_default_language,
|
||||
) = is_language_prefix_patterns_used(urlconf)
|
||||
i18n_patterns_used, _ = is_language_prefix_patterns_used(urlconf)
|
||||
language = translation.get_language_from_request(
|
||||
request, check_path=i18n_patterns_used
|
||||
)
|
||||
language_from_path = translation.get_language_from_path(request.path_info)
|
||||
if (
|
||||
not language_from_path
|
||||
and i18n_patterns_used
|
||||
and not prefixed_default_language
|
||||
):
|
||||
language = settings.LANGUAGE_CODE
|
||||
if not language:
|
||||
language = self.get_fallback_language(request)
|
||||
|
||||
translation.activate(language)
|
||||
request.LANGUAGE_CODE = translation.get_language()
|
||||
|
||||
def process_response(self, request, response):
|
||||
language = translation.get_language()
|
||||
language_from_path = translation.get_language_from_path(request.path_info)
|
||||
language_from_request = translation.get_language_from_request(request)
|
||||
urlconf = getattr(request, "urlconf", settings.ROOT_URLCONF)
|
||||
(
|
||||
i18n_patterns_used,
|
||||
|
@ -48,7 +57,7 @@ class LocaleMiddleware(MiddlewareMixin):
|
|||
response.status_code == 404
|
||||
and not language_from_path
|
||||
and i18n_patterns_used
|
||||
and prefixed_default_language
|
||||
and (prefixed_default_language or language_from_request)
|
||||
):
|
||||
# Maybe the language code is missing in the URL? Try adding the
|
||||
# language prefix and redirecting to that URL.
|
||||
|
|
|
@ -53,7 +53,7 @@ def check_for_language(x):
|
|||
|
||||
|
||||
def get_language_from_request(request, check_path=False):
|
||||
return settings.LANGUAGE_CODE
|
||||
return None
|
||||
|
||||
|
||||
def get_language_from_path(request):
|
||||
|
|
|
@ -578,11 +578,7 @@ def get_language_from_request(request, check_path=False):
|
|||
return get_supported_language_variant(accept_lang)
|
||||
except LookupError:
|
||||
continue
|
||||
|
||||
try:
|
||||
return get_supported_language_variant(settings.LANGUAGE_CODE)
|
||||
except LookupError:
|
||||
return settings.LANGUAGE_CODE
|
||||
return None
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1000)
|
||||
|
|
|
@ -186,6 +186,10 @@ Internationalization
|
|||
|
||||
* Added support and translations for the Central Kurdish (Sorani) language.
|
||||
|
||||
* The :class:`~django.middleware.locale.LocaleMiddleware` now respects a
|
||||
language from the request when :func:`~django.conf.urls.i18n.i18n_patterns`
|
||||
is used with the ``prefix_default_language`` argument set to ``False``.
|
||||
|
||||
Logging
|
||||
~~~~~~~
|
||||
|
||||
|
|
|
@ -2137,8 +2137,22 @@ class UnprefixedDefaultLanguageTests(SimpleTestCase):
|
|||
response = self.client.get("/fr/simple/")
|
||||
self.assertEqual(response.content, b"Oui")
|
||||
|
||||
def test_unprefixed_language_other_than_accept_language(self):
|
||||
def test_unprefixed_language_with_accept_language(self):
|
||||
"""'Accept-Language' is respected."""
|
||||
response = self.client.get("/simple/", HTTP_ACCEPT_LANGUAGE="fr")
|
||||
self.assertRedirects(response, "/fr/simple/")
|
||||
|
||||
def test_unprefixed_language_with_cookie_language(self):
|
||||
"""A language set in the cookies is respected."""
|
||||
self.client.cookies.load({settings.LANGUAGE_COOKIE_NAME: "fr"})
|
||||
response = self.client.get("/simple/")
|
||||
self.assertRedirects(response, "/fr/simple/")
|
||||
|
||||
def test_unprefixed_language_with_non_valid_language(self):
|
||||
response = self.client.get("/simple/", HTTP_ACCEPT_LANGUAGE="fi")
|
||||
self.assertEqual(response.content, b"Yes")
|
||||
self.client.cookies.load({settings.LANGUAGE_COOKIE_NAME: "fi"})
|
||||
response = self.client.get("/simple/")
|
||||
self.assertEqual(response.content, b"Yes")
|
||||
|
||||
def test_page_with_dash(self):
|
||||
|
@ -2214,10 +2228,7 @@ class CountrySpecificLanguageTests(SimpleTestCase):
|
|||
|
||||
def test_get_language_from_request_null(self):
|
||||
lang = trans_null.get_language_from_request(None)
|
||||
self.assertEqual(lang, "en")
|
||||
with override_settings(LANGUAGE_CODE="de"):
|
||||
lang = trans_null.get_language_from_request(None)
|
||||
self.assertEqual(lang, "de")
|
||||
self.assertEqual(lang, None)
|
||||
|
||||
def test_specific_language_codes(self):
|
||||
# issue 11915
|
||||
|
|
Loading…
Reference in New Issue