Opened 2 months ago
Last modified 3 weeks ago
#36488 assigned Bug
RedirectView(query_string=True) produces double '?' when both destination URL and request have query parameters
Reported by: | Ethan Jucovy | Owned by: | Ethan Jucovy |
---|---|---|---|
Component: | Generic views | Version: | 5.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | yes | UI/UX: | no |
Description
When using the generic RedirectView(query_string=True)
with a query string in the destination URL, the view always appends query string parameters from the incoming request with a ?
separator. It should use &
if there's also an existing query string in the incoming URL.
Currently, requests that come in with a query string end up redirected to a URL containing two question marks, e.g.:
path("redirect-me/", RedirectView.as_view(url="/destination/?pork=spam", query_string=True))
GET /redirect-me/?utm_source=foo
Currently results in:
Location: /destination/?pork=spam?utm_source=foo
Expected:
Location: /destination/?pork=spam&utm_source=foo
Change History (5)
comment:1 by , 2 months ago
Has patch: | set |
---|
comment:2 by , 2 months ago
comment:3 by , 2 months ago
Owner: | set to |
---|---|
Status: | new → assigned |
Triage Stage: | Unreviewed → Accepted |
Hello Ethan Jucovy, thank you for taking the time to create this ticket and the PR. I think your report makes sense, I would also expect ?
and &
to be properly handled. Having said that, the current url manipulation logic feels somehow brittle and I wonder if we should consider a more robust implementation using urlparse. Have your given this some thought?
comment:4 by , 2 months ago
Patch needs improvement: | set |
---|
comment:5 by , 3 weeks ago
Hi @EthanJucovy!
I'd love to take on this ticket as my first contribution to Django.
I've analyzed the problem in the get_redirect_url method and have a clean, backward-compatible solution ready. The fix should be just changing the hardcoded '?' separator to use '&' when the destination URL already contains query parameters. Whats your thought about this.
PR: https://github.com/django/django/pull/19610