Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Putting a django login form on every page

I'd like the login form (AuthenticationForm from django.contrib.auth) to appear on every page in my site if the user is not logged in. When the user logs in, they will be redirected to the same page. If there is an error, the error will be shown on the same page with the form.

I suppose you'd need a context processor to provide the form to every template. But, then you'd also need every view to handle the posted form? Does this mean you need to create some middleware? I'm a bit lost.

Is there an accepted way of doing this?

like image 384
asciitaxi Avatar asked Apr 29 '10 00:04

asciitaxi


People also ask

How do I authenticate username and password in Django?

from django. contrib. auth import authenticate user = authenticate(username='john', password='secret') if user is not None: if user. is_active: print "You provided a correct username and password!" else: print "Your account has been disabled!" else: print "Your username and password were incorrect."


1 Answers

Ok, I eventually found a way of doing this, although I'm sure there are better ways. I created a new middleware class called LoginFormMiddleware. In the process_request method, handle the form more or less the way the auth login view does:

class LoginFormMiddleware(object):      def process_request(self, request):          # if the top login form has been posted         if request.method == 'POST' and 'is_top_login_form' in request.POST:              # validate the form             form = AuthenticationForm(data=request.POST)             if form.is_valid():                  # log the user in                 from django.contrib.auth import login                 login(request, form.get_user())                  # if this is the logout page, then redirect to /                 # so we don't get logged out just after logging in                 if '/account/logout/' in request.get_full_path():                     return HttpResponseRedirect('/')          else:             form = AuthenticationForm(request)          # attach the form to the request so it can be accessed within the templates         request.login_form = form 

Now if you have the request context processor installed, you can access the form with:

{{ request.login_form }} 

Note that a hidden field 'is_top_login_form' was added to the form so I could distinguish it from other posted forms on the page. Also, the form action is "." instead of the auth login view.

like image 96
asciitaxi Avatar answered Oct 05 '22 04:10

asciitaxi