【发布时间】:2012-03-22 20:40:35
【问题描述】:
我想在我的网站上随处放置一个登录表单,在遵循一些 SO 答案后,我决定编写自己的中间件,如下所示:
class LoginFormMiddleware(object):
'''
Put a login form in everypage of the website
'''
def process_request(self, request):
# if the top login form has been posted
if request.method == 'POST':
if 'logout_submit' in request.POST:
# log the user out
from django.contrib.auth import logout
logout(request)
form = LoginForm()
elif 'login_submit' in request.POST:
# validate the form
form = LoginForm(data=request.POST)
if form.is_valid():
# log the user in
from django.contrib.auth import login
login(request, form.get_user())
else:
form = LoginForm(request)
else:
form = LoginForm(request)
# attach the form to the request so it can be accessed
# within the templates
request.login_form = form
在我的 settings.py 中,我有:
import django.conf.global_settings as DEFAULT_SETTINGS
...
MIDDLEWARE_CLASSES = DEFAULT_SETTINGS.MIDDLEWARE_CLASSES + (
'base.mymiddleware.LoginFormMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + (
'django.core.context_processors.request',
)
base.html 中要从任何地方访问的表单如下所示:
{% if user.is_authenticated %}
<div class="login_box">
<form action="/myapp/logout/" method="post">{% csrf_token %}
<div class="col2"><a>{{ user.username }}</a></div>
<div class="col3"><input type="submit" value="Logout" name="logout_submit"/></div>
</form>
</div>
{% else %}
<form action="." method="post">
{% csrf_token %}
<div class="login_box">
<div class="error_box">
{% if request.login_form.errors %}
Incorrect User/Password
{% endif %}
</div>
<div class="col00"> <h4>{{ request.login_form.username.label_tag }}</h3></div>
<div class="col11">{{ request.login_form.username }}</div>
<div class="col22"><h4>{{ request.login_form.password.label_tag }}</h3></div>
<div class="col33">{{ request.login_form.password }}</div>
<div class="col44"><input type="submit" value="Login" name="login_submit"/></div>
<input type="hidden" name="next" value="{{ request.get_full_path }}" />
</div>
</form>
{% endif %}
登录工作正常,但是在完成之后,每次我发出 GET 请求 user.is_authenticated 似乎都返回 false,因为我看到的是一个空的 LoginForm 而不是注销表单。
我不知道问题是否出在我的中间件上(当 request.method != 'POST' 它返回 form = LoginForm(request))或者是我的设置中缺少的东西,或者可能为此使用中间件不是个好主意...
【问题讨论】:
-
也请添加您的相关视图。我个人不明白在这种情况下使用中间件的目的,Django 提供了一个不错的模块用于登录和注销。
-
我的观点并没有多大作用,因为所有的工作都在中间件中,事实上,我在里面使用了 django 登录。登录和注销视图只有这一行:return HttpResponseRedirect(request.META.get('HTTP_REFERER'))。使用中间件的好处是因为我希望这个表单在我的站点中无处不在,而不是在 HTML 中
-
Django 的 auth 中间件已经将
user对象添加到模板中的dict中,如果您使用模板继承(应该),您可以将base.html 中的表单,这样它将在每个页面上加载
标签: django forms authentication middleware