Django登录后访问dashboard报405 Method Not Allowed错误求助
Django登录后访问Dashboard触发405 Method Not Allowed错误的解决办法
问题现象
登录页提交登录请求后,直接向/dashboard/发送POST请求,触发HTTP 405 Method Not Allowed错误,但访问其他页面(如dbtable)完全正常。终端报错信息如下:
[02/Oct/2022 17:04:24] "GET / HTTP/1.1" 200 4720
Method Not Allowed (POST): /dashboard/
Method Not Allowed: /dashboard/
[02/Oct/2022 17:04:42] "POST /dashboard/ HTTP/1.1" 405 0
代码问题分析
1. 登录表单提交目标错误
登录表单的action直接指向dashboard路由,且使用POST方法提交,但DashboardPageView继承自TemplateView,默认仅支持GET请求,不处理POST请求,因此返回405错误。
2. 登录视图逻辑存在致命错误
register_login视图中,第一个return render语句写在登录判断代码之前,导致登录相关逻辑永远无法执行;同时条件判断的写法存在逻辑错误,无法正确区分注册和登录请求。
相关代码片段
urls.py
urlpatterns = [ path('',views.register_login, name='login'), path('dashboard/', DashboardPageView.as_view(), name='dashboard'), path('dbtable/', views.DBTableView, name = 'dbtable'), ]
views.py(原错误代码)
def register_login(request): form = UserCreationForm() if "register" in request.method == 'POST': form = UserCreationForm(request.POST) == "Register" if form.is_valid(): form.save() user = form.cleaned_data['username'] messages.success(request,"Account was Created for " + user) context = {'form':form} return render(request,'login.html',context) # 提前返回,后续登录代码无法执行 if "login" in request.method == "POST": if request.POST['submit'] == 'Login': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request,user) return redirect('login') # 登录成功未跳转到dashboard else: messages.error(request, 'Wrong Username or password') context = {} return render(request,'login.html',context) class DashboardPageView(TemplateView): template_name = 'dashboard.html' def get_context_data(self, **kwargs): context = super(DashboardPageView, self).get_context_data(**kwargs) context['plot'] = plot1.cumulative_plot() return context
login.html(原错误代码)
<!-- SIGN IN --> <div class="col align-items-center flex-col sign-in"> <div class="form-wrapper align-items-center"> <div class="form sign-in"> <div class="input-group"> <form action = "{% url 'dashboard' %}" method="POST" name="login" value="login"> {% csrf_token %} <i class='bx bxs-user'></i> <input type="text" name = "username" placeholder="Username" class="form-control" Required> <i class='bx bxs-lock-alt'></i> <input type="password" name = "password" placeholder="Password" class="form-control" Required> <button type="submit" > Sign in </button> <p> <b> Forgot password? </b> </p> <p> <span> Don't have an account? </span> <b onclick="toggle()" class="pointer"> Sign up here </b> </p> </form> </div>
解决方案
步骤1:修正登录表单提交目标
将登录表单的action指向登录视图(当前页面或{% url 'login' %}),同时给提交按钮添加name和value属性,方便视图区分请求类型:
修改后的login.html表单部分:
<form action="{% url 'login' %}" method="POST"> {% csrf_token %} <i class='bx bxs-user'></i> <input type="text" name="username" placeholder="Username" class="form-control" required> <i class='bx bxs-lock-alt'></i> <input type="password" name="password" placeholder="Password" class="form-control" required> <!-- 添加name和value,用于视图判断登录请求 --> <button type="submit" name="submit" value="Login"> Sign in </button> <!-- 注册按钮也需添加对应属性,示例:<button type="submit" name="submit" value="Register">Sign up</button> --> <p> <b>Forgot password?</b> </p> <p> <span>Don't have an account?</span> <b onclick="toggle()" class="pointer">Sign up here</b> </p> </form>
步骤2:修复登录视图逻辑
调整代码顺序,修正条件判断,确保登录、注册逻辑正常执行,且登录成功后重定向到dashboard:
修改后的views.py:
def register_login(request): form = UserCreationForm() if request.method == 'POST': # 处理注册请求 if request.POST.get('submit') == 'Register': form = UserCreationForm(request.POST) if form.is_valid(): form.save() user = form.cleaned_data['username'] messages.success(request, f"Account was Created for {user}") return redirect('login') # 处理登录请求 elif request.POST.get('submit') == 'Login': username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) return redirect('dashboard') # 登录成功跳转到dashboard else: messages.error(request, 'Wrong Username or password') context = {'form': form} return render(request, 'login.html', context) class DashboardPageView(TemplateView): template_name = 'dashboard.html' def get_context_data(self, **kwargs): context = super(DashboardPageView, self).get_context_data(**kwargs) context['plot'] = plot1.cumulative_plot() return context
额外说明
TemplateView默认仅处理GET请求,无需修改它支持POST,登录逻辑应在专门的登录视图中完成,再通过重定向访问dashboard(GET请求),这符合HTTP最佳实践,还能避免页面刷新时重复提交表单的问题。
内容的提问来源于stack exchange,提问作者dv_confusedcoder
相关产品推荐
相关产品推荐

