Django LoginFormMiddleware breaks with class based views

前端 未结 2 953
無奈伤痛
無奈伤痛 2021-01-26 11:56

As per a few other SO answers, I\'m using middleware to show a login form on every page of my project, such that a user can login in-place. I am aware some frown upon this, but

2条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-26 12:40

    To finalize this question, Alasdair's answer is spot on. The final code I'm using is

    from MyProj.forms import MyProjTopLoginForm
    from django.http import HttpResponseRedirect
    from django.core.urlresolvers import reverse
    
    #Notes: http://stackoverflow.com/questions/2734055/putting-a-django-login-form-on-every-page
    class LoginFormMiddleware(object):
    
        def process_request(self, request):
    
            # if the top login form has been posted
            if request.method == 'POST' and 'top_login_form-username' in request.POST:
    
                # validate the form
                form = MyProjTopLoginForm(prefix="top_login_form", 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 reverse('logout') in request.get_full_path():
                        return HttpResponseRedirect('/')
                    # Redirect to the same page after successfully handling the login form data.
                    return HttpResponseRedirect('')
                    # We could also do:
                    # request.method = 'GET'
                    # instead of a redirect, but if a user refreshes the page, they'll get prompted to re-send post data,
                    # which is super annoying.
    
            else:
                form = MyProjTopLoginForm(request, prefix="top_login_form")
    
            # attach the form to the request so it can be accessed within the templates
            request.top_login_form = form
    
    class LogoutFormMiddleware(object):
        def process_request(self, request):
            if request.method == 'POST' and request.POST.has_key('logout-button') and request.POST['logout-button'] == 'logout':
                from django.contrib.auth import logout
                logout(request)
                # Same as above. Handle the post data, then redirect to a new GET (not POST) request. 
                return HttpResponseRedirect('')
    

    This solves the original issue, as well as issuing a redirect upon successful handling of (login, logout) data so that a user-triggered refresh doesn't prompt to resend the form.

提交回复
热议问题