Django如何修改默认登录模板路径为webpage/index.html并解决自定义后登录失败问题
你现在碰到的核心问题根本不是模板路径配错了,是写了自定义的登录视图但没把它接到对应的请求路由上,同时首页的表单没有绑定到登录处理逻辑,才会出现单独放registration/login.html能工作、挪到index.html就失效的情况,按下面的步骤改就行:
第一步:把自定义登录视图绑定到登录路由
你之前写的WebpageLoginView只是个类,没有挂到Django的请求处理流程里,相当于代码写了但没生效。
如果你的项目之前是直接用Django自带的auth路由(也就是path('accounts/', include('django.contrib.auth.urls'))),那自带的逻辑还是会走默认的LoginView,去找registration/login.html模板,根本不会执行你写的自定义视图。
你需要在urls.py里把原来默认的登录路由替换成自己写的类视图:
from django.urls import path from webpage.views import WebpageLoginView # 导入你定义好的自定义登录视图 urlpatterns = [ # 替换默认的登录路由 path('accounts/login/', WebpageLoginView.as_view(), name='login'), # 其他auth相关的路由(登出、密码修改等)可以正常保留,不影响功能 path('accounts/', include('django.contrib.auth.urls')), # 你原来的首页路由正常保留就行 path('', index, name='index'), ]
第二步:修正index.html上的登录表单提交地址
你之前在index.html里写的表单是<form method="post">,不写action的话,提交的时候会把POST请求打到当前页面的URL(也就是首页路径/),但你的首页视图根本没有处理登录校验的逻辑,自然没法完成登录。
把表单改成指定提交到你刚才配置的登录路由就行:
<form method="post" action="{% url 'login' %}"> {% csrf_token %} {{ form.as_p }} <button type="submit">Login</button> </form>
因为你已经在WebpageLoginView里指定了template_name = 'webpage/index.html',所以不管是用户访问登录路由、还是提交登录表单,视图最终渲染的都是你的index.html,不会跳转到单独的登录页。
第三步:解决index页表单不渲染、登录跳转不对的问题
这里有两个非常容易踩的坑:
- 当你直接访问首页的时候,首页的视图没有把登录表单的实例传给模板,会导致页面上的
{{ form }}是空的,连用户名、密码输入框都出不来。你需要在自己写的首页视图里,手动把认证表单传给模板:from django.contrib.auth.forms import AuthenticationForm def index(request): # 把认证表单实例传给模板,确保登录输入框正常渲染 return render(request, 'webpage/index.html', {'form': AuthenticationForm()}) - 登录成功后如果不想跳转到默认的
/accounts/profile/路径,直接在自定义的WebpageLoginView里指定成功跳转的地址就行,不用改全局settings配置:from django.contrib.auth.views import LoginView from django.urls import reverse_lazy class WebpageLoginView(LoginView): template_name = 'webpage/index.html' # 登录成功后跳回首页 success_url = reverse_lazy('index')
改完之后的逻辑是通的:用户打开首页,能看到完整的登录表单,提交表单的时候会把请求发到专门处理登录校验的/accounts/login/路由,验证通过后跳回首页,验证失败也会带着错误信息重新渲染首页,全程不会跳转到单独的登录页面。
内容的提问来源于stack exchange,提问作者dxb

