Skip to content

Commit a36df68

Browse files
Samriddha9619ejucovynessita
authored andcommitted
Fixed #36488 -- Fixed merging of query strings in RedirectView.
Co-authored-by: Ethan Jucovy <ethan.jucovy@gmail.com> Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
1 parent 336e713 commit a36df68

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

django/views/generic/base.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logging
2+
from urllib.parse import urlparse
23

34
from asgiref.sync import iscoroutinefunction, markcoroutinefunction
45

@@ -252,7 +253,10 @@ def get_redirect_url(self, *args, **kwargs):
252253

253254
args = self.request.META.get("QUERY_STRING", "")
254255
if args and self.query_string:
255-
url = "%s?%s" % (url, args)
256+
if urlparse(url).query:
257+
url = f"{url}&{args}"
258+
else:
259+
url = f"{url}?{args}"
256260
return url
257261

258262
def get(self, request, *args, **kwargs):

tests/generic_views/test_base.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,31 @@ def test_gone_response_logged(self):
587587
handler, f"Gone: {escaped}", logging.WARNING, 410, request
588588
)
589589

590+
def test_redirect_with_querry_string_in_destination(self):
591+
response = RedirectView.as_view(url="/bar/?pork=spam", query_string=True)(
592+
self.rf.get("/foo")
593+
)
594+
self.assertEqual(response.status_code, 302)
595+
self.assertEqual(response.headers["Location"], "/bar/?pork=spam")
596+
597+
def test_redirect_with_query_string_in_destination_and_request(self):
598+
response = RedirectView.as_view(url="/bar/?pork=spam", query_string=True)(
599+
self.rf.get("/foo/?utm_source=social")
600+
)
601+
self.assertEqual(response.status_code, 302)
602+
self.assertEqual(
603+
response.headers["Location"], "/bar/?pork=spam&utm_source=social"
604+
)
605+
606+
def test_redirect_with_same_query_string_param_will_append_not_replace(self):
607+
response = RedirectView.as_view(url="/bar/?pork=spam", query_string=True)(
608+
self.rf.get("/foo/?utm_source=social&pork=ham")
609+
)
610+
self.assertEqual(response.status_code, 302)
611+
self.assertEqual(
612+
response.headers["Location"], "/bar/?pork=spam&utm_source=social&pork=ham"
613+
)
614+
590615

591616
class GetContextDataTest(SimpleTestCase):
592617
def test_get_context_data_super(self):

0 commit comments

Comments
 (0)