views:

1024

answers:

3

The Django framework easily handles redirecting when a user fails to log in properly. However, this redirection goes to a separate login page. I can set the template to be the same as the page I logged in on, but none of my other objects exist in the new page.

For example, I have a front page that shows a bunch of news articles. On the sidebar is a login form. When the user logs in, but fails to authenticate, I would like it to return to the front page and preserve all the news articles that show. As of current, none of the news articles show up.

How can I fix this problem? Any help is appreciated.

Edit: Remember that I have dynamic content that is being displayed, and I would like it to still display! Futhermore, the main page is not the only place a user can log in. The sidebar never changes, so the user can potentially log in from any page on the site, and all of the content on that page exactly as it was still needs to be displayed upon failure to log in.

+2  A: 

Do you want to redirect to the referring page on failed login?

... authentication code above

if user.is_authenticated():
    #show success view
else:
    return HttpResponseRedirect(request.META['HTTP_REFERER'])

you might want to check that referring page url is set correctly, otherwise set it to default url.

Evgeny
How would I do this if I'm using django.contrib.auth.views.login ?
AlbertoPL
@AlbertoPL that view does not have redirect on failure
Evgeny
@AlbertoPL there's function authenticate() - look it up in the manual - i've got to go :)
Evgeny
HttpResponseRedirect sends me back to where I came but without any of the dictionary parameters I had before, thus nothing shows up.
AlbertoPL
yes you will lose the query string of the previous request - you can either preserve it through session or as a hidden field in the login form.
Evgeny
A: 

This is coz, redirecting to a view, misses the original context you used to render the page in first place.

You are missing just a simple logic here. You are trying to render the same template again, but with no news_article list.

I suppose (in first place), you are rendering the template which shows you Articles as well as login form, by sending two things 1. Login Form, 2. Articles list. But secondly, when user fails to authenticate, you are not passing same things again. Pass those variables again as context (you can also add error message if your form is not handling error messages).

if user.is_authenticated():
    #show success view
else:
    return render_to_response('same_template.html', {
        'error_msg': 'Username or password you provided was incorrect',
        'news_articles': NewsArticles.objects.all()[:3],
        'login_form': LoginForm(request.POST);
    })

Edit: The ultimate reality is that, a context is used to render a template, and its the complete responsibility of that template, what it wants to pass in further navigation. And as i see, if you are not passing something further, you are not getting it further.

If you want some automated context, develop your own context processor, something like the auth-context-processor, which automatically adds like 'user', always available to the template.

And BTW, you are anyway going to miss that kind of context, even if login is authenticated. So if that particular context is really important, either try sending the primary keys of articles along with the login form submit, or store that in global (ugliest thing ever) or just reconsider and separate the flow (good thing i feel).

simplyharsh
If in case you are using Django Forms then No need to pass error message that will do the needful :)
aatifh
I wont necessarily be displaying all news articles. For example, someone may have done a search which filtered out some of the news articles that were displayed. I need to be able to display the same number of articles as before.
AlbertoPL
Alright, I will investigate what you have said and post my findings.
AlbertoPL
A: 
  1. Use an <IFRAME> in the sidebar to call the login view -- all postbacks will happen within the iframe, so your page stays intact. If the visitor logs in successfully, you can use javascript to redirect the parent page to some other URL
  2. Use AJAX to post the login form -- acheives the same effect as (1), but it means your visitors will need to have javascript-enabled browsers

I personally prefer to have the login on a separate page. If you're only worried about your visitors losing their current page (and not say, bound by a fussy client), you can have the login show up in a lightbox. I've used all three approaches in the past, and I'd be happy to post some code samples if you're interested.

elo80ka