Django登录失败重定向后表单输入框消失问题求助
问题描述
使用Django开发用户登录页面时,当用户登录凭证错误,页面返回登录页,但表单输入字段消失,无法输入内容。点击导航栏指向"/login"的登录按钮时,表单显示及功能正常,仅在postlogin视图执行后出现输入框消失的情况。
问题表现
- postlogin视图执行后:登录页无输入表单
- 正常登录页:表单显示正常,可输入
相关代码
登录与postlogin视图
def login(request): # Rendering login page assert isinstance(request, HttpRequest) return render( request, 'app/login.html', { 'title': 'Login', 'message': 'Login to your account', 'year': datetime.now().year, 'form':form } ) def postlogin(request): email=request.POST.get('email') pasw=request.POST.get('password') try: # if there is no error then signin the user with given email and password user = authe.sign_in_with_email_and_password(email, pasw) except: message="Invalid credentials!" # return to login page if password and email was invalid return render(request,"app/login.html", {'message':message, 'current_user': authe.current_user}) # set current session with user token session_id=user['idToken'] request.session['uid']=str(session_id) return render(request,"app/home.html", {"email":email, 'current_user': authe.current_user})
urls.py
from datetime import datetime from django.urls import path from django.contrib import admin from django.contrib.auth.views import LoginView, LogoutView from app import forms from app import views urlpatterns = [ path('', views.home, name='home'), path('contact/', views.contact, name='contact'), path('about/', views.about, name='about'), path('login/', LoginView.as_view ( template_name='app/login.html', authentication_form=forms.BootstrapAuthenticationForm, extra_context= { 'title': 'Log in', 'year' : datetime.now().year, } ), name='login'), path('postlogin/', views.postlogin, name='postlogin'), path('postsignup/', views.postsignup, name='postsignup'), #path('logout/', LogoutView.as_view(next_page=''), name='logout'), path('logout/', views.logout, name='logout'), path('admin/', admin.site.urls), ]
forms.py
from django import forms from django.contrib.auth.forms import AuthenticationForm, UserCreationForm from django.utils.translation import ugettext_lazy as _ class BootstrapAuthenticationForm(AuthenticationForm): """Authentication form which uses boostrap CSS.""" email = forms.CharField(max_length=254, widget=forms.TextInput({ 'class': 'form-control', 'placeholder': 'Email'})) password = forms.CharField(label=_('Password'), widget=forms.PasswordInput({ 'class': 'form-control', 'placeholder':'Password'}))
login.html
{% block content %} <h2>{{ title }}</h2> {% if current_user %} <form id="logoutForm" action="/logout/" method="post" class="navbar-right"> {% csrf_token %} <ul class="nav navbar-nav navbar-right"> <li><span class="navbar-brand">Hello {{ user.username }}!</span></li> <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li> </ul> </form> {% else %} <ul class="nav navbar-nav navbar-right"> <li><a href="/login/">Log in</a></li> </ul> {% endif %} <div class="row"> <div class="col-md-8"> <section id="loginForm"> <form action="/postlogin/" method="post" class="form-horizontal"> {% csrf_token %} <h4>Use a local account to log in.</h4> <hr /> <div class="form-group"> <label for="id_username" class="col-md-2 control-label">Email</label> <div class="col-md-10"> {{ form.email }} </div> </div> <div class="form-group"> <label for="id_password" class="col-md-2 control-label">Password</label> <div class="col-md-10"> {{ form.password }} </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="hidden" name="next" value="/" /> <input type="submit" value="Log in" class="btn btn-default" /> </div> </div> {% if form.errors %} <p class="validation-summary-errors">Please enter a correct user name and password.</p> {% endif %} </form> </section> </div> <div class="col-md-4"> <section id="socialLoginForm"></section> </div> </div> {% endblock %} {% block scripts %} {% load staticfiles %} <script src="{% static 'app/scripts/jquery.validate.min.js' %}"></script> {% endblock %}
解决方案
问题根源
postlogin视图验证失败返回登录页时,没有向模板传递form实例,而模板中渲染输入框完全依赖{{ form.email }}和{{ form.password }}变量,导致表单字段无法显示。另外,自定义的login视图中直接使用未实例化的form变量,本身也存在语法错误。
修复步骤
修正postlogin视图的异常处理逻辑
验证失败时,实例化BootstrapAuthenticationForm并传递给模板,同时补充模板所需的其他变量:from app.forms import BootstrapAuthenticationForm from datetime import datetime def postlogin(request): email=request.POST.get('email') pasw=request.POST.get('password') try: user = authe.sign_in_with_email_and_password(email, pasw) except: message="Invalid credentials!" # 实例化表单并传递给模板 form = BootstrapAuthenticationForm() return render(request,"app/login.html", { 'message': message, 'current_user': authe.current_user, 'form': form, 'title': 'Login', 'year': datetime.now().year }) # 其余登录成功逻辑不变 session_id=user['idToken'] request.session['uid']=str(session_id) return render(request,"app/home.html", {"email":email, 'current_user': authe.current_user})修复自定义login视图的错误
原视图中未实例化form变量,需补充表单实例化代码:from app.forms import BootstrapAuthenticationForm from datetime import datetime def login(request): assert isinstance(request, HttpRequest) form = BootstrapAuthenticationForm() # 实例化表单 return render( request, 'app/login.html', { 'title': 'Login', 'message': 'Login to your account', 'year': datetime.now().year, 'form': form } )优化模板错误提示(可选)
模板中可同时显示自定义错误信息和表单原生错误,修改提示部分:{% if message %} <p class="validation-summary-errors">{{ message }}</p> {% endif %} {% if form.errors %} <p class="validation-summary-errors">请输入正确的邮箱和密码。</p> {% endif %}
内容的提问来源于stack exchange,提问作者thewaterbuffalo
相关产品推荐
相关产品推荐

