summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAhmad A. Hussein <ahmadahussein0@gmail.com>2020-05-27 08:10:08 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-05-27 10:36:52 +0200
commit7c947f0f5a0539add9adf8c4e14726ea509e13ef (patch)
tree90974bb4b3de86fa3d46769a87e55b7bc068ed98
parent6425fd3124e50219ba0b6f545d1bf7edfb053a59 (diff)
Fixed #31494 -- Preserved query strings when following HTTP 307/308 redirects in test client.
-rw-r--r--django/test/client.py8
-rw-r--r--docs/releases/3.2.txt3
-rw-r--r--tests/test_client/tests.py14
3 files changed, 23 insertions, 2 deletions
diff --git a/django/test/client.py b/django/test/client.py
index b26504f762..ce74a5fe53 100644
--- a/django/test/client.py
+++ b/django/test/client.py
@@ -826,8 +826,12 @@ class Client(ClientMixin, RequestFactory):
path = urljoin(response.request['PATH_INFO'], path)
if response.status_code in (HTTPStatus.TEMPORARY_REDIRECT, HTTPStatus.PERMANENT_REDIRECT):
- # Preserve request method post-redirect for 307/308 responses.
- request_method = getattr(self, response.request['REQUEST_METHOD'].lower())
+ # Preserve request method and query string (if needed)
+ # post-redirect for 307/308 responses.
+ request_method = response.request['REQUEST_METHOD'].lower()
+ if request_method not in ('get', 'head'):
+ extra['QUERY_STRING'] = url.query
+ request_method = getattr(self, request_method)
else:
request_method = self.get
data = QueryDict(url.query)
diff --git a/docs/releases/3.2.txt b/docs/releases/3.2.txt
index 2d49299440..84f757cd2b 100644
--- a/docs/releases/3.2.txt
+++ b/docs/releases/3.2.txt
@@ -214,6 +214,9 @@ Tests
creating deep copies with :py:func:`copy.deepcopy`. Assigning objects which
don't support ``deepcopy()`` is deprecated and will be removed in Django 4.1.
+* :class:`~django.test.Client` now preserves the request query string when
+ following 307 and 308 redirects.
+
URLs
~~~~
diff --git a/tests/test_client/tests.py b/tests/test_client/tests.py
index 0b63a3fed5..03bb658952 100644
--- a/tests/test_client/tests.py
+++ b/tests/test_client/tests.py
@@ -284,6 +284,20 @@ class ClientTest(TestCase):
self.assertEqual(response.request['PATH_INFO'], '/post_view/')
self.assertEqual(response.request['REQUEST_METHOD'], method.upper())
+ def test_follow_307_and_308_preserves_query_string(self):
+ methods = ('post', 'options', 'put', 'patch', 'delete', 'trace')
+ codes = (307, 308)
+ for method, code in itertools.product(methods, codes):
+ with self.subTest(method=method, code=code):
+ req_method = getattr(self.client, method)
+ response = req_method(
+ '/redirect_view_%s_query_string/' % code,
+ data={'value': 'test'},
+ follow=True,
+ )
+ self.assertRedirects(response, '/post_view/?hello=world', status_code=code)
+ self.assertEqual(response.request['QUERY_STRING'], 'hello=world')
+
def test_follow_307_and_308_get_head_query_string(self):
methods = ('get', 'head')
codes = (307, 308)