根据几个other SO answers,我使用中间件在我的项目的每个页面上显示登录表单,以便用户可以在原地登录。我知道有些人对此感到不满,但它的确提供了更好的用户体验。理想情况下它会是异步的,但我还没有到达那里。Django LoginForm中间件基于类视图
反正middleware.py:
from MyProj.forms import MyProjTopLoginForm
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
#Notes: https://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('/')
#return HttpResponseRedirect('/')
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)
request.method = 'GET'
和views.py:
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.db.models import Count
from django.core.urlresolvers import reverse
from django.views.generic import TemplateView
class Index(TemplateView):
template_name = 'KReport2/index.djhtml'
'''
def index(request):
return render(request, 'KReport2/index.djhtml')
'''
def logoutpage(request):
from django.contrib.auth import logout
logout(request)
return redirect(index)
你会注意到,我的评论旧索引视图功能,并以团体取代了它基于视图。通常我不会继承子类,而是在urls.py中传递template_name,但这里除了这一点之外。我的问题似乎是中间件断了。在索引页填写UN/Pass,然后提交,中间件捕获表单并将我登录,但是然后django继续返回一个空白的http响应。没有错误,但也没有渲染索引页面。我只是不知道休息是在哪里发生的。
巨大!很好的回答,谢谢。虽然我发现LogoutFormMiddleware已经解决了这个问题,只需在注销之后通过设置request.method ='GET'来完成,这样视图就可以通过GET方法结束处理,从而解决问题。在我看来,最好是发布重定向到相同的URL,虽然我不确定优点会是什么(可能是一点速度) – 2013-04-23 22:45:16
不重定向理论上更快,但我不知道如果用户会注意到实践中的任何差异。改变中间件中的'request.method'对我来说似乎很难受。就个人而言,我会避免这样做。在成功发布帖子后重新定向是一个很好的习惯。在这种情况下,这不是必需的,因为没有风险例如两次处理付款。如果用户在登录后立即刷新页面,重定向将阻止用户获得“是否要重新提交请求”确认消息。我认为这是一个可用性改进。 – Alasdair 2013-04-24 00:13:20
是的,我完全同意,很好的捕捉。重定向它。 – 2013-04-25 00:18:40