Fixed #15318 -- Added settings for language cookie max-age, path, domain
Introduced a number of settings to configure max-age, path, and domain for the language cookie: LANGUAGE_COOKIE_AGE, LANGUAGE_COOKIE_PATH and LANGUAGE_COOKIE_DOMAIN. Thanks sahid for the suggestion.
This commit is contained in:
parent
c679cb7f60
commit
8c98f39624
|
@ -140,7 +140,13 @@ LANGUAGES_BIDI = ("he", "ar", "fa", "ur")
|
||||||
# to load the internationalization machinery.
|
# to load the internationalization machinery.
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
LOCALE_PATHS = ()
|
LOCALE_PATHS = ()
|
||||||
|
|
||||||
|
# Settings for language cookie
|
||||||
LANGUAGE_COOKIE_NAME = 'django_language'
|
LANGUAGE_COOKIE_NAME = 'django_language'
|
||||||
|
LANGUAGE_COOKIE_AGE = None
|
||||||
|
LANGUAGE_COOKIE_DOMAIN = None
|
||||||
|
LANGUAGE_COOKIE_PATH = '/'
|
||||||
|
|
||||||
|
|
||||||
# If you set this to True, Django will format dates, numbers and calendars
|
# If you set this to True, Django will format dates, numbers and calendars
|
||||||
# according to user current locale.
|
# according to user current locale.
|
||||||
|
|
|
@ -38,7 +38,10 @@ def set_language(request):
|
||||||
if hasattr(request, 'session'):
|
if hasattr(request, 'session'):
|
||||||
request.session[LANGUAGE_SESSION_KEY] = lang_code
|
request.session[LANGUAGE_SESSION_KEY] = lang_code
|
||||||
else:
|
else:
|
||||||
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)
|
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code,
|
||||||
|
max_age=settings.LANGUAGE_COOKIE_AGE,
|
||||||
|
path=settings.LANGUAGE_COOKIE_PATH,
|
||||||
|
domain=settings.LANGUAGE_COOKIE_DOMAIN)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1362,6 +1362,40 @@ See :ref:`how-django-discovers-language-preference` for more details.
|
||||||
|
|
||||||
.. _list of language identifiers: http://www.i18nguy.com/unicode/language-identifiers.html
|
.. _list of language identifiers: http://www.i18nguy.com/unicode/language-identifiers.html
|
||||||
|
|
||||||
|
.. setting:: LANGUAGE_COOKIE_AGE
|
||||||
|
|
||||||
|
LANGUAGE_COOKIE_AGE
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
.. versionadded:: 1.7
|
||||||
|
|
||||||
|
Default: ``None`` (expires at browser close)
|
||||||
|
|
||||||
|
The age of the language cookie, in seconds.
|
||||||
|
|
||||||
|
.. setting:: LANGUAGE_COOKIE_DOMAIN
|
||||||
|
|
||||||
|
LANGUAGE_COOKIE_DOMAIN
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
.. versionadded:: 1.7
|
||||||
|
|
||||||
|
Default: ``None``
|
||||||
|
|
||||||
|
The domain to use for the language cookie. Set this to a string such as
|
||||||
|
``".example.com"`` (note the leading dot!) for cross-domain cookies, or use
|
||||||
|
``None`` for a standard domain cookie.
|
||||||
|
|
||||||
|
Be cautious when updating this setting on a production site. If you update
|
||||||
|
this setting to enable cross-domain cookies on a site that previously used
|
||||||
|
standard domain cookies, existing user cookies that have the old domain
|
||||||
|
will not be updated. This will result in site users being unable to switch
|
||||||
|
the language as long as these cookies persist. The only safe and reliable
|
||||||
|
option to perform the switch is to change the language cookie name
|
||||||
|
permanently (via the :setting:`SESSION_COOKIE_NAME` setting) and to add
|
||||||
|
a middleware that copies the value from the old cookie to a new one and then
|
||||||
|
deletes the old one.
|
||||||
|
|
||||||
.. setting:: LANGUAGE_COOKIE_NAME
|
.. setting:: LANGUAGE_COOKIE_NAME
|
||||||
|
|
||||||
LANGUAGE_COOKIE_NAME
|
LANGUAGE_COOKIE_NAME
|
||||||
|
@ -1373,6 +1407,31 @@ The name of the cookie to use for the language cookie. This can be whatever
|
||||||
you want (but should be different from :setting:`SESSION_COOKIE_NAME`). See
|
you want (but should be different from :setting:`SESSION_COOKIE_NAME`). See
|
||||||
:doc:`/topics/i18n/index`.
|
:doc:`/topics/i18n/index`.
|
||||||
|
|
||||||
|
.. setting:: LANGUAGE_COOKIE_PATH
|
||||||
|
|
||||||
|
LANGUAGE_COOKIE_PATH
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
.. versionadded:: 1.7
|
||||||
|
|
||||||
|
Default: ``/``
|
||||||
|
|
||||||
|
The path set on the language cookie. This should either match the URL path of your
|
||||||
|
Django installation or be a parent of that path.
|
||||||
|
|
||||||
|
This is useful if you have multiple Django instances running under the same
|
||||||
|
hostname. They can use different cookie paths and each instance will only see
|
||||||
|
its own language cookie.
|
||||||
|
|
||||||
|
Be cautious when updating this setting on a production site. If you update this
|
||||||
|
setting to use a deeper path than it previously used, existing user cookies that
|
||||||
|
have the old path will not be updated. This will result in site users being
|
||||||
|
unable to switch the language as long as these cookies persist. The only safe
|
||||||
|
and reliable option to perform the switch is to change the language cookie name
|
||||||
|
permanently (via the :setting:`SESSION_COOKIE_NAME` setting), and to add
|
||||||
|
a middleware that copies the value from the old cookie to a new one and then
|
||||||
|
deletes the one.
|
||||||
|
|
||||||
.. setting:: LANGUAGES
|
.. setting:: LANGUAGES
|
||||||
|
|
||||||
LANGUAGES
|
LANGUAGES
|
||||||
|
@ -2801,7 +2860,10 @@ Globalization (i18n/l10n)
|
||||||
* :setting:`FIRST_DAY_OF_WEEK`
|
* :setting:`FIRST_DAY_OF_WEEK`
|
||||||
* :setting:`FORMAT_MODULE_PATH`
|
* :setting:`FORMAT_MODULE_PATH`
|
||||||
* :setting:`LANGUAGE_CODE`
|
* :setting:`LANGUAGE_CODE`
|
||||||
|
* :setting:`LANGUAGE_COOKIE_AGE`
|
||||||
|
* :setting:`LANGUAGE_COOKIE_DOMAIN`
|
||||||
* :setting:`LANGUAGE_COOKIE_NAME`
|
* :setting:`LANGUAGE_COOKIE_NAME`
|
||||||
|
* :setting:`LANGUAGE_COOKIE_PATH`
|
||||||
* :setting:`LANGUAGES`
|
* :setting:`LANGUAGES`
|
||||||
* :setting:`LOCALE_PATHS`
|
* :setting:`LOCALE_PATHS`
|
||||||
* :setting:`MONTH_DAY_FORMAT`
|
* :setting:`MONTH_DAY_FORMAT`
|
||||||
|
|
|
@ -559,6 +559,10 @@ Internationalization
|
||||||
app or project message file. See :ref:`how-to-create-language-files` for
|
app or project message file. See :ref:`how-to-create-language-files` for
|
||||||
details.
|
details.
|
||||||
|
|
||||||
|
* The following settings to adjust the language cookie options were introduced:
|
||||||
|
:setting:`LANGUAGE_COOKIE_AGE`, :setting:`LANGUAGE_COOKIE_DOMAIN`
|
||||||
|
and :setting:`LANGUAGE_COOKIE_PATH`.
|
||||||
|
|
||||||
* Added :ref:`format definitions <format-localization>` for Esperanto.
|
* Added :ref:`format definitions <format-localization>` for Esperanto.
|
||||||
|
|
||||||
Management Commands
|
Management Commands
|
||||||
|
|
|
@ -1575,6 +1575,20 @@ which returns the language used in the current thread,
|
||||||
for the current thread, and ``django.utils.translation.check_for_language()``
|
for the current thread, and ``django.utils.translation.check_for_language()``
|
||||||
which checks if the given language is supported by Django.
|
which checks if the given language is supported by Django.
|
||||||
|
|
||||||
|
Language cookie
|
||||||
|
---------------
|
||||||
|
|
||||||
|
A number of settings can be used to adjust language cookie options:
|
||||||
|
|
||||||
|
* :setting:`LANGUAGE_COOKIE_NAME`
|
||||||
|
|
||||||
|
.. versionadded:: 1.7
|
||||||
|
|
||||||
|
* :setting:`LANGUAGE_COOKIE_AGE`
|
||||||
|
* :setting:`LANGUAGE_COOKIE_DOMAIN`
|
||||||
|
* :setting:`LANGUAGE_COOKIE_PATH`
|
||||||
|
|
||||||
|
|
||||||
Implementation notes
|
Implementation notes
|
||||||
====================
|
====================
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,25 @@ class I18NTests(TestCase):
|
||||||
def test_setlang_reversal(self):
|
def test_setlang_reversal(self):
|
||||||
self.assertEqual(reverse('set_language'), '/i18n/setlang/')
|
self.assertEqual(reverse('set_language'), '/i18n/setlang/')
|
||||||
|
|
||||||
|
def test_setlang_cookie(self):
|
||||||
|
# we force saving language to a cookie rather than a session
|
||||||
|
# by excluding session middleware and those which do require it
|
||||||
|
test_settings = dict(
|
||||||
|
MIDDLEWARE_CLASSES=('django.middleware.common.CommonMiddleware',),
|
||||||
|
LANGUAGE_COOKIE_NAME='mylanguage',
|
||||||
|
LANGUAGE_COOKIE_AGE=3600 * 7 * 2,
|
||||||
|
LANGUAGE_COOKIE_DOMAIN='.example.com',
|
||||||
|
LANGUAGE_COOKIE_PATH='/test/',
|
||||||
|
)
|
||||||
|
with self.settings(**test_settings):
|
||||||
|
post_data = dict(language='pl', next='/views/')
|
||||||
|
response = self.client.post('/i18n/setlang/', data=post_data)
|
||||||
|
language_cookie = response.cookies.get('mylanguage')
|
||||||
|
self.assertEqual(language_cookie.value, 'pl')
|
||||||
|
self.assertEqual(language_cookie['domain'], '.example.com')
|
||||||
|
self.assertEqual(language_cookie['path'], '/test/')
|
||||||
|
self.assertEqual(language_cookie['max-age'], 3600 * 7 * 2)
|
||||||
|
|
||||||
def test_jsi18n(self):
|
def test_jsi18n(self):
|
||||||
"""The javascript_catalog can be deployed with language settings"""
|
"""The javascript_catalog can be deployed with language settings"""
|
||||||
for lang_code in ['es', 'fr', 'ru']:
|
for lang_code in ['es', 'fr', 'ru']:
|
||||||
|
|
Loading…
Reference in New Issue