Refs #15902 -- Made set_language() view always set the current language in a cookie.

The plan is to later deprecate/remove storing the language in the session.
This commit is contained in:
Claude Paroz 2017-12-02 13:00:30 +01:00 committed by Tim Graham
parent ccc25bfe4f
commit b3cd9fb18b
3 changed files with 23 additions and 14 deletions

View File

@ -22,9 +22,9 @@ LANGUAGE_QUERY_PARAMETER = 'language'
def set_language(request): def set_language(request):
""" """
Redirect to a given URL while setting the chosen language in the session or Redirect to a given URL while setting the chosen language in the session
cookie. The URL and the language code need to be specified in the request (if enabled) and in a cookie. The URL and the language code need to be
parameters. specified in the request parameters.
Since this view changes how the user will see the rest of the site, it must Since this view changes how the user will see the rest of the site, it must
only be accessed as a POST request. If called as a GET request, it will only be accessed as a POST request. If called as a GET request, it will
@ -49,13 +49,12 @@ def set_language(request):
response = HttpResponseRedirect(next_trans) response = HttpResponseRedirect(next_trans)
if hasattr(request, 'session'): if hasattr(request, 'session'):
request.session[LANGUAGE_SESSION_KEY] = lang_code request.session[LANGUAGE_SESSION_KEY] = lang_code
else: response.set_cookie(
response.set_cookie( settings.LANGUAGE_COOKIE_NAME, lang_code,
settings.LANGUAGE_COOKIE_NAME, lang_code, max_age=settings.LANGUAGE_COOKIE_AGE,
max_age=settings.LANGUAGE_COOKIE_AGE, path=settings.LANGUAGE_COOKIE_PATH,
path=settings.LANGUAGE_COOKIE_PATH, domain=settings.LANGUAGE_COOKIE_DOMAIN,
domain=settings.LANGUAGE_COOKIE_DOMAIN, )
)
return response return response

View File

@ -1761,10 +1761,14 @@ Activate this view by adding the following line to your URLconf::
language-independent itself to work correctly. language-independent itself to work correctly.
The view expects to be called via the ``POST`` method, with a ``language`` The view expects to be called via the ``POST`` method, with a ``language``
parameter set in request. If session support is enabled, the view parameter set in request. If session support is enabled, the view saves the
saves the language choice in the user's session. Otherwise, it saves the language choice in the user's session. It also saves the language choice in a
language choice in a cookie that is by default named ``django_language``. cookie that is named ``django_language`` by default. (The name can be changed
(The name can be changed through the :setting:`LANGUAGE_COOKIE_NAME` setting.) through the :setting:`LANGUAGE_COOKIE_NAME` setting.)
.. versionchanged:: 2.1
In older versions, the cookie is only set if session support isn't enabled.
After setting the language choice, Django looks for a ``next`` parameter in the After setting the language choice, Django looks for a ``next`` parameter in the
``POST`` or ``GET`` data. If that is found and Django considers it to be a safe ``POST`` or ``GET`` data. If that is found and Django considers it to be a safe

View File

@ -37,6 +37,12 @@ class SetLanguageTests(TestCase):
response = self.client.post('/i18n/setlang/', post_data, HTTP_REFERER='/i_should_not_be_used/') response = self.client.post('/i18n/setlang/', post_data, HTTP_REFERER='/i_should_not_be_used/')
self.assertRedirects(response, '/') self.assertRedirects(response, '/')
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code) self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
# The language is set in a cookie.
language_cookie = self.client.cookies[settings.LANGUAGE_COOKIE_NAME]
self.assertEqual(language_cookie.value, lang_code)
self.assertEqual(language_cookie['domain'], '')
self.assertEqual(language_cookie['path'], '/')
self.assertEqual(language_cookie['max-age'], '')
def test_setlang_unsafe_next(self): def test_setlang_unsafe_next(self):
""" """