1
0
mirror of https://github.com/django/django.git synced 2025-06-05 11:39:13 +00:00

Refs #15902 -- Stopped set_language() storing user's language in the session.

Per deprecation timeline.
This commit is contained in:
Mariusz Felisiak 2021-01-06 13:16:24 +01:00
parent 52a238ddf2
commit d134b0b93e
8 changed files with 15 additions and 92 deletions

View File

@ -1,7 +1,6 @@
import base64 import base64
import logging import logging
import string import string
import warnings
from datetime import datetime, timedelta from datetime import datetime, timedelta
from django.conf import settings from django.conf import settings
@ -12,9 +11,7 @@ from django.utils import timezone
from django.utils.crypto import ( from django.utils.crypto import (
constant_time_compare, get_random_string, salted_hmac, constant_time_compare, get_random_string, salted_hmac,
) )
from django.utils.deprecation import RemovedInDjango40Warning
from django.utils.module_loading import import_string from django.utils.module_loading import import_string
from django.utils.translation import LANGUAGE_SESSION_KEY
# session_key should not be case sensitive because some backends can store it # session_key should not be case sensitive because some backends can store it
# on case insensitive file systems. # on case insensitive file systems.
@ -55,13 +52,6 @@ class SessionBase:
return key in self._session return key in self._session
def __getitem__(self, key): def __getitem__(self, key):
if key == LANGUAGE_SESSION_KEY:
warnings.warn(
'The user language will no longer be stored in '
'request.session in Django 4.0. Read it from '
'request.COOKIES[settings.LANGUAGE_COOKIE_NAME] instead.',
RemovedInDjango40Warning, stacklevel=2,
)
return self._session[key] return self._session[key]
def __setitem__(self, key, value): def __setitem__(self, key, value):

View File

@ -17,11 +17,8 @@ __all__ = [
'ngettext', 'ngettext_lazy', 'ngettext', 'ngettext_lazy',
'pgettext', 'pgettext_lazy', 'pgettext', 'pgettext_lazy',
'npgettext', 'npgettext_lazy', 'npgettext', 'npgettext_lazy',
'LANGUAGE_SESSION_KEY',
] ]
LANGUAGE_SESSION_KEY = '_language'
class TranslatorCommentWarning(SyntaxWarning): class TranslatorCommentWarning(SyntaxWarning):
pass pass

View File

@ -11,9 +11,7 @@ from django.template import Context, Engine
from django.urls import translate_url from django.urls import translate_url
from django.utils.formats import get_format from django.utils.formats import get_format
from django.utils.http import url_has_allowed_host_and_scheme from django.utils.http import url_has_allowed_host_and_scheme
from django.utils.translation import ( from django.utils.translation import check_for_language, get_language
LANGUAGE_SESSION_KEY, check_for_language, get_language,
)
from django.utils.translation.trans_real import DjangoTranslation from django.utils.translation.trans_real import DjangoTranslation
from django.views.generic import View from django.views.generic import View
@ -57,10 +55,6 @@ def set_language(request):
next_trans = translate_url(next_url, lang_code) next_trans = translate_url(next_url, lang_code)
if next_trans != next_url: if next_trans != next_url:
response = HttpResponseRedirect(next_trans) response = HttpResponseRedirect(next_trans)
if hasattr(request, 'session'):
# Storing the language in the session is deprecated.
# (RemovedInDjango40Warning)
request.session[LANGUAGE_SESSION_KEY] = lang_code
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,

View File

@ -1099,13 +1099,3 @@ For a complete discussion on the usage of the following see the
Turns a Django template into something that is understood by ``xgettext``. Turns a Django template into something that is understood by ``xgettext``.
It does so by translating the Django translation tags into standard It does so by translating the Django translation tags into standard
``gettext`` function invocations. ``gettext`` function invocations.
.. data:: LANGUAGE_SESSION_KEY
Session key under which the active language for the current session is
stored.
.. deprecated:: 3.0
The language won't be stored in the session in Django 4.0. Use the
:setting:`LANGUAGE_COOKIE_NAME` cookie instead.

View File

@ -663,12 +663,11 @@ Internationalization
* The :class:`~django.middleware.locale.LocaleMiddleware` now stores the user's * The :class:`~django.middleware.locale.LocaleMiddleware` now stores the user's
selected language with the session key ``_language``. This should only be selected language with the session key ``_language``. This should only be
accessed using the :data:`~django.utils.translation.LANGUAGE_SESSION_KEY` accessed using the ``LANGUAGE_SESSION_KEY`` constant. Previously it was
constant. Previously it was stored with the key ``django_language`` and the stored with the key ``django_language`` and the ``LANGUAGE_SESSION_KEY``
``LANGUAGE_SESSION_KEY`` constant did not exist, but keys reserved for Django constant did not exist, but keys reserved for Django should start with an
should start with an underscore. For backwards compatibility ``django_language`` underscore. For backwards compatibility ``django_language`` is still read
is still read from in 1.7. Sessions will be migrated to the new key from in 1.7. Sessions will be migrated to the new key as they are written.
as they are written.
* The :ttag:`blocktrans` tag now supports a ``trimmed`` option. This * The :ttag:`blocktrans` tag now supports a ``trimmed`` option. This
option will remove newline characters from the beginning and the end of the option will remove newline characters from the beginning and the end of the

View File

@ -254,6 +254,9 @@ to remove usage of these features.
* ``django.utils.translation.ugettext()``, ``ugettext_lazy()``, * ``django.utils.translation.ugettext()``, ``ugettext_lazy()``,
``ugettext_noop()``, ``ungettext()``, and ``ungettext_lazy()`` are removed. ``ugettext_noop()``, ``ungettext()``, and ``ungettext_lazy()`` are removed.
* ``django.views.i18n.set_language()`` doesn't set the user language in
``request.session`` (key ``_language``).
See :ref:`deprecated-features-3.1` for details on these changes, including how See :ref:`deprecated-features-3.1` for details on these changes, including how
to remove usage of these features. to remove usage of these features.

View File

@ -29,11 +29,10 @@ from django.utils.formats import (
from django.utils.numberformat import format as nformat from django.utils.numberformat import format as nformat
from django.utils.safestring import SafeString, mark_safe from django.utils.safestring import SafeString, mark_safe
from django.utils.translation import ( from django.utils.translation import (
LANGUAGE_SESSION_KEY, activate, check_for_language, deactivate, activate, check_for_language, deactivate, get_language, get_language_bidi,
get_language, get_language_bidi, get_language_from_request, get_language_from_request, get_language_info, gettext, gettext_lazy,
get_language_info, gettext, gettext_lazy, ngettext, ngettext_lazy, ngettext, ngettext_lazy, npgettext, npgettext_lazy, pgettext,
npgettext, npgettext_lazy, pgettext, round_away_from_one, to_language, round_away_from_one, to_language, to_locale, trans_null, trans_real,
to_locale, trans_null, trans_real,
) )
from django.utils.translation.reloader import ( from django.utils.translation.reloader import (
translation_file_changed, watch_for_translation_changes, translation_file_changed, watch_for_translation_changes,
@ -1684,21 +1683,6 @@ class LocaleMiddlewareTests(TestCase):
response = self.client.get('/en/streaming/') response = self.client.get('/en/streaming/')
self.assertContains(response, "Yes/No") self.assertContains(response, "Yes/No")
@override_settings(
MIDDLEWARE=[
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
],
)
def test_language_not_saved_to_session(self):
"""
The Current language isno' automatically saved to the session on every
request (#21473).
"""
self.client.get('/fr/simple/')
self.assertNotIn(LANGUAGE_SESSION_KEY, self.client.session)
@override_settings( @override_settings(
USE_I18N=True, USE_I18N=True,

View File

@ -4,15 +4,12 @@ from os import path
from django.conf import settings from django.conf import settings
from django.test import ( from django.test import (
RequestFactory, SimpleTestCase, TestCase, ignore_warnings, modify_settings, RequestFactory, SimpleTestCase, TestCase, modify_settings,
override_settings, override_settings,
) )
from django.test.selenium import SeleniumTestCase from django.test.selenium import SeleniumTestCase
from django.urls import reverse from django.urls import reverse
from django.utils.deprecation import RemovedInDjango40Warning from django.utils.translation import get_language, override
from django.utils.translation import (
LANGUAGE_SESSION_KEY, get_language, override,
)
from django.views.i18n import JavaScriptCatalog, get_formats from django.views.i18n import JavaScriptCatalog, get_formats
from ..urls import locale_dir from ..urls import locale_dir
@ -37,8 +34,6 @@ class SetLanguageTests(TestCase):
post_data = {'language': lang_code, 'next': '/'} post_data = {'language': lang_code, 'next': '/'}
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, '/')
with ignore_warnings(category=RemovedInDjango40Warning):
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
# The language is set in a cookie. # The language is set in a cookie.
language_cookie = self.client.cookies[settings.LANGUAGE_COOKIE_NAME] language_cookie = self.client.cookies[settings.LANGUAGE_COOKIE_NAME]
self.assertEqual(language_cookie.value, lang_code) self.assertEqual(language_cookie.value, lang_code)
@ -59,8 +54,6 @@ class SetLanguageTests(TestCase):
response = self.client.post('/i18n/setlang/', data=post_data) response = self.client.post('/i18n/setlang/', data=post_data)
self.assertEqual(response.url, '/') self.assertEqual(response.url, '/')
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code) self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
with ignore_warnings(category=RemovedInDjango40Warning):
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def test_setlang_http_next(self): def test_setlang_http_next(self):
""" """
@ -74,14 +67,10 @@ class SetLanguageTests(TestCase):
response = self.client.post('/i18n/setlang/', data=post_data, secure=True) response = self.client.post('/i18n/setlang/', data=post_data, secure=True)
self.assertEqual(response.url, '/') self.assertEqual(response.url, '/')
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code) self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
with ignore_warnings(category=RemovedInDjango40Warning):
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
# Insecure URL in HTTP referer. # Insecure URL in HTTP referer.
response = self.client.post('/i18n/setlang/', secure=True, HTTP_REFERER=non_https_next_url) response = self.client.post('/i18n/setlang/', secure=True, HTTP_REFERER=non_https_next_url)
self.assertEqual(response.url, '/') self.assertEqual(response.url, '/')
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code) self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
with ignore_warnings(category=RemovedInDjango40Warning):
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def test_setlang_redirect_to_referer(self): def test_setlang_redirect_to_referer(self):
""" """
@ -93,8 +82,6 @@ class SetLanguageTests(TestCase):
response = self.client.post('/i18n/setlang/', post_data, HTTP_REFERER='/i18n/') response = self.client.post('/i18n/setlang/', post_data, HTTP_REFERER='/i18n/')
self.assertRedirects(response, '/i18n/', fetch_redirect_response=False) self.assertRedirects(response, '/i18n/', fetch_redirect_response=False)
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code) self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
with ignore_warnings(category=RemovedInDjango40Warning):
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def test_setlang_default_redirect(self): def test_setlang_default_redirect(self):
""" """
@ -106,8 +93,6 @@ class SetLanguageTests(TestCase):
response = self.client.post('/i18n/setlang/', post_data) response = self.client.post('/i18n/setlang/', post_data)
self.assertRedirects(response, '/') self.assertRedirects(response, '/')
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code) self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
with ignore_warnings(category=RemovedInDjango40Warning):
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def test_setlang_performs_redirect_for_ajax_if_explicitly_requested(self): def test_setlang_performs_redirect_for_ajax_if_explicitly_requested(self):
""" """
@ -119,8 +104,6 @@ class SetLanguageTests(TestCase):
response = self.client.post('/i18n/setlang/', post_data, HTTP_ACCEPT='application/json') response = self.client.post('/i18n/setlang/', post_data, HTTP_ACCEPT='application/json')
self.assertRedirects(response, '/') self.assertRedirects(response, '/')
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code) self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
with ignore_warnings(category=RemovedInDjango40Warning):
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def test_setlang_doesnt_perform_a_redirect_to_referer_for_ajax(self): def test_setlang_doesnt_perform_a_redirect_to_referer_for_ajax(self):
""" """
@ -133,8 +116,6 @@ class SetLanguageTests(TestCase):
response = self.client.post('/i18n/setlang/', post_data, **headers) response = self.client.post('/i18n/setlang/', post_data, **headers)
self.assertEqual(response.status_code, 204) self.assertEqual(response.status_code, 204)
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code) self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
with ignore_warnings(category=RemovedInDjango40Warning):
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def test_setlang_doesnt_perform_a_default_redirect_for_ajax(self): def test_setlang_doesnt_perform_a_default_redirect_for_ajax(self):
""" """
@ -146,8 +127,6 @@ class SetLanguageTests(TestCase):
response = self.client.post('/i18n/setlang/', post_data, HTTP_ACCEPT='application/json') response = self.client.post('/i18n/setlang/', post_data, HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 204) self.assertEqual(response.status_code, 204)
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code) self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
with ignore_warnings(category=RemovedInDjango40Warning):
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
def test_setlang_unsafe_next_for_ajax(self): def test_setlang_unsafe_next_for_ajax(self):
""" """
@ -160,15 +139,6 @@ class SetLanguageTests(TestCase):
self.assertEqual(response.url, '/') self.assertEqual(response.url, '/')
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code) self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
def test_session_language_deprecation(self):
msg = (
'The user language will no longer be stored in request.session '
'in Django 4.0. Read it from '
'request.COOKIES[settings.LANGUAGE_COOKIE_NAME] instead.'
)
with self.assertRaisesMessage(RemovedInDjango40Warning, msg):
self.client.session[LANGUAGE_SESSION_KEY]
def test_setlang_reversal(self): def test_setlang_reversal(self):
self.assertEqual(reverse('set_language'), '/i18n/setlang/') self.assertEqual(reverse('set_language'), '/i18n/setlang/')
@ -208,8 +178,6 @@ class SetLanguageTests(TestCase):
response = self.client.post('/i18n/setlang/', {'language': lang_code}, HTTP_REFERER=encoded_url) response = self.client.post('/i18n/setlang/', {'language': lang_code}, HTTP_REFERER=encoded_url)
self.assertRedirects(response, encoded_url, fetch_redirect_response=False) self.assertRedirects(response, encoded_url, fetch_redirect_response=False)
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code) self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, lang_code)
with ignore_warnings(category=RemovedInDjango40Warning):
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], lang_code)
@modify_settings(MIDDLEWARE={ @modify_settings(MIDDLEWARE={
'append': 'django.middleware.locale.LocaleMiddleware', 'append': 'django.middleware.locale.LocaleMiddleware',
@ -220,8 +188,6 @@ class SetLanguageTests(TestCase):
follow=True, HTTP_REFERER='/en/translated/' follow=True, HTTP_REFERER='/en/translated/'
) )
self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, 'nl') self.assertEqual(self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value, 'nl')
with ignore_warnings(category=RemovedInDjango40Warning):
self.assertEqual(self.client.session[LANGUAGE_SESSION_KEY], 'nl')
self.assertRedirects(response, '/nl/vertaald/') self.assertRedirects(response, '/nl/vertaald/')
# And reverse # And reverse
response = self.client.post( response = self.client.post(