Login and Redirect
-
26-09-2019 - |
Question
This is my login views:
def login(request):
redirect_to = request.REQUEST.get("next")
if request.method == 'POST':
formL = LoginForm(data=request.POST)
if formL.is_valid():
if not redirect_to or '//' in redirect_to or ' ' in redirect_to:
redirect_to = "/blogs/"
from django.contrib.auth import login
login(request, formL.get_user())
if request.session.test_cookie_worked():
request.session.delete_test_cookie()
return HttpResponseRedirect(redirect_to)
else:
formL = LoginForm(request)
request.session.set_test_cookie()
return render_to_response('blogs.html', {
'formL': formL, }, context_instance=RequestContext(request))
login = never_cache(login)
When I go, for example, to example.com/myblog/ then I have been redirect to example.com/accounts/login/?next=/myblog/
but when I insert user and psw for login then I have been redirect to /blogs/ and not /myblog/
Why ?
Edit: request.REQUEST.get('next', '') always return ''
I don't know why :-\
Solution
How does your login form template look like?
Your problem
You are not sending the redirect_to
path to your template and you should. Your return should look like this:
return render_to_response('blogs.html', {
'formL': formL,
'next': redirect_to,
}, context_instance=RequestContext(request)
)
The login form action should look like this:
<form action="/your_login_url/?next={{ next }}" method="post">
So when you go to /myblog/
you get redirected to /your_login_url/?next=/myblog/
, the login view then renders the login form and replaces the next
variable in login form action attribute so it looks like /your_login_url/?next=/myblog/
and when you submit the form you get logged in and redirected to /myblog/
(stuff after if request.method == 'POST':
gets executed).
In your view, redirect_to = request.REQUEST.get("next")
works fine when you only GET
the login page but when you POST
to it there is not next
variable set in GET.
Also note
Login view shouldn't render your blog, blogs view should do that.
This is how Django's returned response looks like, note the line where it says redirect_field_name: redirect_to,
, redirect_field_name
has the value of next
by default.
return render_to_response(template_name, {
'form': form,
redirect_field_name: redirect_to,
'site': current_site,
'site_name': current_site.name,
}, context_instance=RequestContext(request))
And, you seem to override the login view only for default redirection? This isn't right IMHO. The right place to set default location for login redirection is in your settings.py by setting LOGIN_REDIRECT_URL.
But, since you are writing your own login view why not use the one in django as a skeleton and then expand on it what you need.
OTHER TIPS
Because
not redirect_to or '//' in redirect_to or ' ' in redirect_to
evaluates to True?
Maybe if we teach the man to fish? http://docs.python.org/library/logging.html
Put this at the top
import logging
LOG_FILENAME = '/tmp/logging_example.out'
logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)
Put this where it seems appropriate in your code (eg after the if statement)
logging.debug("redirect_to = %s" % redirect_to)
Run it, then look at the contents of '/tmp/logging_example.out'