FreedomBox/plinth/translation.py
Sunil Mohan Adapa 5d0a7c6d16
translation: Don't use session for storing lang pref in Django 4.0
Helps: #2228.

- In Django 3.0, storing language preference in session key is deprecated and
only the language cookie is used. In Django 4.0, this functionality is
completely removed along with the constant LANGUAGE_SESSION_KEY.

- Debian stable (Bullseye) uses Django 2.2 and this depends on code to store
language preference in session key. To work on Django 2.2 through 4.0, check if
the constant is available and then set the session key of the constant is found.

Tests:

- Change language in user edit page and see that it is persisted.

- After logout, the new language is still set.

- Changing language as anonymous user works.

- Run tests in stable, testing and unstable containers.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2022-06-20 08:15:58 -04:00

65 lines
1.8 KiB
Python

# SPDX-License-Identifier: AGPL-3.0-or-later
"""
Utility methods for managing translations.
"""
from django.conf import settings
from django.utils import translation
def _should_use_sessions(request):
return hasattr(request, 'session') and hasattr(translation,
'LANGUAGE_SESSION_KEY')
def get_language_from_request(request):
"""Get the language in the session or as separate cookie.
Django methods should be used for regular cases. This is only useful for
very narrow cases.
"""
if _should_use_sessions(request):
language_code = request.session.get(translation.LANGUAGE_SESSION_KEY)
if language_code:
return language_code
return request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)
def set_language(request, response, language_code):
"""Set the language in session or as a separate cookie.
Sending language code as None removes the preference. response is not
optional as Django 3.0 up always set the language cookie and Django 4.0
will no longer set the language in the session.
"""
if not language_code:
if _should_use_sessions(request):
try:
del request.session[translation.LANGUAGE_SESSION_KEY]
except KeyError:
pass
if response:
try:
response.delete_cookie(settings.LANGUAGE_COOKIE_NAME)
except KeyError:
pass
return
translation.activate(language_code)
if _should_use_sessions(request):
request.session[translation.LANGUAGE_SESSION_KEY] = language_code
response.set_cookie(
settings.LANGUAGE_COOKIE_NAME,
language_code,
max_age=settings.LANGUAGE_COOKIE_AGE,
path=settings.LANGUAGE_COOKIE_PATH,
domain=settings.LANGUAGE_COOKIE_DOMAIN,
)