views:

90

answers:

2
+1  Q: 

Login and Redirect

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 :-\

+1  A: 

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'

John Mee
yes but why it is true ?Is this wrong ? : redirect_to = request.REQUEST.get("next")
xRobot
+1  A: 

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/?=/myblog/, the login view then renders the login form and replaces the next variable int login form action 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 djangos 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.

rebus
Honestly, all your statements separately I understand and make sense, but your whole story is not clear at all. Please be more consistent with names and reasons. E.g. you're talking about redirect_to, but you use {{ next }} in the template, you get the url tag out of nowhere, and you're talking about LOGIN_REDIRECT_URL, which is for global redirection, specific redirection is passed by default through 'next', so he IS right there. However, you are right again he can extend the default login easier (just override the template).
KillianDS
erm... ok so i am not the worlds best english writer, heck i can barely spell croatian correctly, but aside that, i've edited my answer a bit based on your objections, but still `redirect_to = "/blogs/"` is not right thing to do, the right thing is to use global redirection,LOGIN_REDIRECT_URL that is, cos that's why it's there. Also, you are more then welcome to copy my answer and edit it so it gives an example of how the answer should look like.
rebus
you right thanks ;)
xRobot