elethan elethan - 5 months ago 23
Python Question

Is Django login redirect stripping my url parameters?

In my URLconf I have the following url (where

login
is the built-in login view function from
django.contrib.auth.views
):

url(r'^login/', login, name='login', kwargs={
'template_name': 'topspots/login.html',
'redirect_field_name': 'next',
})


Then in my template, in a navbar that is present on all pages on the site, I have the following login link:

<li><a href="{% url 'login' %}?next={{ request.get_full_path }}">Log in</a></li>


When I visit the login page from, e.g., the search results page, the url I get in the address bar is something like:

http://localhost:8000/login/?next=/spots/search/?search_query=South+Oak+Park%2C+KCMO%2C+MO%2C+United+States&searchtype=default&latitude=38.97600750000001&longitude=-94.58623399999999


which seems right to me (note the
longitude
and
latitude
parameters), because after logging in, I would like to be redirected to

http://localhost:8000/spots/search/?search_query=South+Oak+Park%2C+KCMO%2C+MO%2C+United+States&searchtype=default&latitude=38.97600750000001&longitude=-94.58623399999999


i.e., the
next
path. However, from the login view, the value of
{{ next }}
ends up being
/spots/search/?search_query=South Oak Park, KCMO, MO, United States
. In other words, all the parameters except for the first one have been stripped. I have not been able to figure when/where/why these parameters are getting chopped off. Is this something Django is doing, or does it stem from a mistake of mine? If it is Django, I am sure there is a good reason for it, but if it is just me doing something wrong, I would like to fix it. Any suggestions? Thank you!

Answer

What happens is that your generated url ends up being parsed like so:

next=/spots/search/?search_query=South+Oak+Park%2C+KCMO%2C+MO%2C+United+States
searchtype=default
latitude=38.97600750000001
longitude=-94.58623399999999

The additional parameters are no longer part of the next url, so they get dropped. To avoid this, encode the entire url so it stays together:

<li><a href="{% url 'login' %}?next={{ request.get_full_path|urlencode }}">Log in</a></li>

The & character gets encoded so the browser no longer splits the parameters and sends them to the wrong url.

Django documentation.

Comments