Fixed #33562 -- Made HttpResponse.set_cookie() support timedelta for the max_age argument.
This commit is contained in:
parent
1882f6567d
commit
ae2da5ba65
|
@ -227,6 +227,10 @@ class HttpResponseBase:
|
||||||
- a naive ``datetime.datetime`` object in UTC,
|
- a naive ``datetime.datetime`` object in UTC,
|
||||||
- an aware ``datetime.datetime`` object in any time zone.
|
- an aware ``datetime.datetime`` object in any time zone.
|
||||||
If it is a ``datetime.datetime`` object then calculate ``max_age``.
|
If it is a ``datetime.datetime`` object then calculate ``max_age``.
|
||||||
|
|
||||||
|
``max_age`` can be:
|
||||||
|
- int/float specifying seconds,
|
||||||
|
- ``datetime.timedelta`` object.
|
||||||
"""
|
"""
|
||||||
self.cookies[key] = value
|
self.cookies[key] = value
|
||||||
if expires is not None:
|
if expires is not None:
|
||||||
|
@ -246,6 +250,8 @@ class HttpResponseBase:
|
||||||
else:
|
else:
|
||||||
self.cookies[key]["expires"] = ""
|
self.cookies[key]["expires"] = ""
|
||||||
if max_age is not None:
|
if max_age is not None:
|
||||||
|
if isinstance(max_age, datetime.timedelta):
|
||||||
|
max_age = max_age.total_seconds()
|
||||||
self.cookies[key]["max-age"] = int(max_age)
|
self.cookies[key]["max-age"] = int(max_age)
|
||||||
# IE requires expires, so set it if hasn't been already.
|
# IE requires expires, so set it if hasn't been already.
|
||||||
if not expires:
|
if not expires:
|
||||||
|
|
|
@ -853,9 +853,15 @@ Methods
|
||||||
Sets a cookie. The parameters are the same as in the
|
Sets a cookie. The parameters are the same as in the
|
||||||
:class:`~http.cookies.Morsel` cookie object in the Python standard library.
|
:class:`~http.cookies.Morsel` cookie object in the Python standard library.
|
||||||
|
|
||||||
* ``max_age`` should be an integer number of seconds, or ``None`` (default)
|
* ``max_age`` should be a :class:`~datetime.timedelta` object, an integer
|
||||||
if the cookie should last only as long as the client's browser session.
|
number of seconds, or ``None`` (default) if the cookie should last only
|
||||||
If ``expires`` is not specified, it will be calculated.
|
as long as the client's browser session. If ``expires`` is not specified,
|
||||||
|
it will be calculated.
|
||||||
|
|
||||||
|
.. versionchanged:: 4.1
|
||||||
|
|
||||||
|
Support for ``timedelta`` objects was added.
|
||||||
|
|
||||||
* ``expires`` should either be a string in the format
|
* ``expires`` should either be a string in the format
|
||||||
``"Wdy, DD-Mon-YY HH:MM:SS GMT"`` or a ``datetime.datetime`` object
|
``"Wdy, DD-Mon-YY HH:MM:SS GMT"`` or a ``datetime.datetime`` object
|
||||||
in UTC. If ``expires`` is a ``datetime`` object, the ``max_age``
|
in UTC. If ``expires`` is a ``datetime`` object, the ``max_age``
|
||||||
|
|
|
@ -281,7 +281,8 @@ Models
|
||||||
Requests and Responses
|
Requests and Responses
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
* ...
|
* :meth:`.HttpResponse.set_cookie` now supports :class:`~datetime.timedelta`
|
||||||
|
objects for the ``max_age`` argument.
|
||||||
|
|
||||||
Security
|
Security
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
|
@ -71,6 +71,11 @@ class SetCookieTests(SimpleTestCase):
|
||||||
response.set_cookie("max_age", max_age=10.6)
|
response.set_cookie("max_age", max_age=10.6)
|
||||||
self.assertEqual(response.cookies["max_age"]["max-age"], 10)
|
self.assertEqual(response.cookies["max_age"]["max-age"], 10)
|
||||||
|
|
||||||
|
def test_max_age_timedelta(self):
|
||||||
|
response = HttpResponse()
|
||||||
|
response.set_cookie("max_age", max_age=timedelta(hours=1))
|
||||||
|
self.assertEqual(response.cookies["max_age"]["max-age"], 3600)
|
||||||
|
|
||||||
def test_httponly_cookie(self):
|
def test_httponly_cookie(self):
|
||||||
response = HttpResponse()
|
response = HttpResponse()
|
||||||
response.set_cookie("example", httponly=True)
|
response.set_cookie("example", httponly=True)
|
||||||
|
|
|
@ -62,6 +62,13 @@ class SignedCookieTest(SimpleTestCase):
|
||||||
with self.assertRaises(signing.SignatureExpired):
|
with self.assertRaises(signing.SignatureExpired):
|
||||||
request.get_signed_cookie("c", max_age=timedelta(seconds=10))
|
request.get_signed_cookie("c", max_age=timedelta(seconds=10))
|
||||||
|
|
||||||
|
def test_set_signed_cookie_max_age_argument(self):
|
||||||
|
response = HttpResponse()
|
||||||
|
response.set_signed_cookie("c", "value", max_age=100)
|
||||||
|
self.assertEqual(response.cookies["c"]["max-age"], 100)
|
||||||
|
response.set_signed_cookie("d", "value", max_age=timedelta(hours=2))
|
||||||
|
self.assertEqual(response.cookies["d"]["max-age"], 7200)
|
||||||
|
|
||||||
@override_settings(SECRET_KEY=b"\xe7")
|
@override_settings(SECRET_KEY=b"\xe7")
|
||||||
def test_signed_cookies_with_binary_key(self):
|
def test_signed_cookies_with_binary_key(self):
|
||||||
response = HttpResponse()
|
response = HttpResponse()
|
||||||
|
|
Loading…
Reference in New Issue