django-中间件问题
我想在我的网站上到处都放一个登录表单,在回答了几个问题后,我决定像这样编写自己的中间件:django-中间件问题,django,forms,authentication,middleware,Django,Forms,Authentication,Middleware,我想在我的网站上到处都放一个登录表单,在回答了几个问题后,我决定像这样编写自己的中间件: 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':
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
{% 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 %}
在my 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表单如下所示:
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
{% 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 %}
{%if user.u经过身份验证%}
{%csrf_令牌%}
{{user.username}
{%else%}
{%csrf_令牌%}
{%if request.login_form.errors%}
用户/密码不正确
{%endif%}
{{request.login\u form.username.label\u tag}
{{request.login_form.username}
{{request.login\u form.password.label\u tag}
{{request.login_form.password}}
{%endif%}
登录正常工作,但每次我发出GET请求user.is_authenticated似乎都返回false,因为我看到的是一个空的LoginForm,而不是注销表单
我不知道问题是否出在我的中间件中(当request.method!=“POST”返回form=LoginForm(request)),或者我的设置中缺少了它,或者可能使用中间件来解决这个问题不是一个好主意……您的实现没有多大意义。具有操作属性的登录表单“”错误,将导致冲突 您应该有一个登录视图,而不是登录中间件。登录表单的action属性应该是登录视图的反向url 在登录表单中,应指定下一个隐藏输入,例如:
<input name="next" type="hidden" value="{{ request.POST.next|default:request.path }}" />
接下来,它可以在您的基本模板中,也可以在网站的任何位置
这对于注销也是有效的。我不相信您看到过任何支持将这种逻辑放入中间件的答案。(如果你有,发布链接,这样我就可以否决他们。) 这真的,真的,真的不是做这种事情的地方。编写特定视图并将登录表单的操作参数设置为该视图
但是,我怀疑您的潜在问题是您没有使用RequestContext呈现其他视图,因此用户对象没有传递到模板。请也添加相关视图。我个人不理解在这种情况下使用中间件的目的,Django本身提供了一个不错的登录和注销模块。我的观点没有多大作用,因为所有的工作都在中间件中,事实上,我在中间件中使用Django登录。登录和注销视图只有一行:returnhttpresponseredirect(request.META.get('HTTP\u REFERER'))。使用中间件的目的是因为我希望在我的站点的任何地方都使用此表单,而不是在HTML apartDjango的auth中间件中,它已经将
user
对象添加到模板的dict
,如果使用模板继承(应该),可以将表单放在base.HTML中,这样,它将加载到每个page@juankysmith这就是为什么我们有@login\u required
decorator,抱歉我不知道,但我看不出decorator与每次查看后显示表单之间的关系,所以。。。我必须在每个视图的返回中传递表单吗?为什么要这样做?只需粘贴表单的HTML即可。这就是我们在betspire.com上看到的,它简单而理智。是的,我想做的是像betspire一样登录。它是否使用视图进行登录?是的,/account/login/。但是基本模板允许用户从任何页面进入该页面。如何返回该视图?