diff --git a/django/contrib/sessions/backends/base.py b/django/contrib/sessions/backends/base.py index 10d564b752..a395b589b1 100644 --- a/django/contrib/sessions/backends/base.py +++ b/django/contrib/sessions/backends/base.py @@ -295,10 +295,7 @@ class SessionBase: """ Create a new session key, while retaining the current session data. """ - try: - data = self._session_cache - except AttributeError: - data = {} + data = self._session key = self.session_key self.create() self._session_cache = data diff --git a/django/contrib/sessions/backends/signed_cookies.py b/django/contrib/sessions/backends/signed_cookies.py index 6391b3ef3e..1ee7790b8e 100644 --- a/django/contrib/sessions/backends/signed_cookies.py +++ b/django/contrib/sessions/backends/signed_cookies.py @@ -71,9 +71,8 @@ class SessionStore(SessionBase): Instead of generating a random string, generate a secure url-safe base64-encoded string of data as our session key. """ - session_cache = getattr(self, '_session_cache', {}) return signing.dumps( - session_cache, compress=True, + self._session, compress=True, salt='django.contrib.sessions.backends.signed_cookies', serializer=self.serializer, ) diff --git a/docs/releases/1.11.1.txt b/docs/releases/1.11.1.txt index 953a6e8889..41f82a0c63 100644 --- a/docs/releases/1.11.1.txt +++ b/docs/releases/1.11.1.txt @@ -27,3 +27,6 @@ Bugfixes * Restored ``BoundField``\s without any ``choices`` evaluating to ``True`` (:ticket:`28058`). + +* Prevented ``SessionBase.cycle_key()`` from losing session data if + ``_session_cache`` isn't populated (:ticket:`28066`). diff --git a/tests/sessions_tests/tests.py b/tests/sessions_tests/tests.py index 9654c7d9eb..bf1e05fbec 100644 --- a/tests/sessions_tests/tests.py +++ b/tests/sessions_tests/tests.py @@ -178,8 +178,13 @@ class SessionTestsMixin: self.assertEqual(list(self.session.items()), prev_data) def test_cycle_with_no_session_cache(self): + self.session['a'], self.session['b'] = 'c', 'd' + self.session.save() + prev_data = list(self.session.items()) + self.session = self.backend(self.session.session_key) self.assertFalse(hasattr(self.session, '_session_cache')) self.session.cycle_key() + self.assertEqual(list(self.session.items()), prev_data) def test_save_doesnt_clear_data(self): self.session['a'] = 'b'