Django重写contrib.auth登录流程POST请求无法捕获问题
Django自定义登录无法捕获POST、错误提示不显示的修复方案
核心问题点
- 重写的
form_valid方法签名和父类LoginView不匹配,缺少必填的form参数,且方法内没有返回响应对象,自定义逻辑根本不会被正常执行 - 类作用域下直接写的
print("check")仅会在项目启动、类加载时执行一次,和单次请求处理没有任何关系 - 单独封装的
custom_login函数在校验失败时直接返回纯文本响应,不会回退到登录页渲染,错误消息自然无法展示 - 模板使用了
{% static %}标签但未提前加载,会直接抛模板错误 - 没必要重复实现用户名密码校验逻辑,Django内置的
AuthenticationForm已经封装了完整的校验、认证流程,只需要在对应钩子加自定义提示即可。
修复代码
views.py
删除冗余的custom_login函数,正确重写LoginView的成功/失败钩子:
from django.contrib import messages from django.contrib.auth import login from django.contrib.auth.views import LoginView from django.shortcuts import render, redirect from django.urls import reverse_lazy def index(request): return render(request, 'index.html') def templates(request): return render(request, 'templates.html') def information(request): return render(request, 'information.html') class CustomLoginView(LoginView): template_name = 'accounts/login.html' success_url = reverse_lazy('index') def form_valid(self, form): user = form.get_user() login(self.request, user) messages.success(self.request, '登录成功') return redirect(self.get_success_url()) def form_invalid(self, form): messages.error(self.request, '用户名或密码错误') return super().form_invalid(form)
urls.py
确保自定义登录路由在内置auth路由的前面,避免被内置路由覆盖:
from django.contrib import admin from django.urls import path, include from ArtisticCode import views urlpatterns = [ path('admin/', admin.site.urls), path('accounts/login/', views.CustomLoginView.as_view(), name='login'), path('accounts/', include('django.contrib.auth.urls')), path('', views.index, name='index'), path('templates/', views.templates, name='templates'), path('information/', views.information, name='information'), ]
accounts/login.html
顶部补充static标签加载语句:
{% load static %} <form method="post" class="login"> {% csrf_token %} <div class="login_input"> <img src="{% static 'img/bx_img1.png' %}" alt="image"/> <input type="text" placeholder="Username" name="username" required/> </div> <div class="login_input"> <img src="{% static 'img/bx_img1.png' %}" alt="image"/> <input type="password" placeholder="Password" name="password" required/> </div> <input type="submit" value="Send message"/> {% if messages %} {% for message in messages %} <strong style="color:white;">{{ message }}</strong> {% endfor %} {% endif %} </form>
settings.py补充检查
确保INSTALLED_APPS中包含django.contrib.staticfiles,否则static标签无法正常使用,已配置的消息中间件、认证中间件不需要调整。
注意:重写Django类视图的方法时,必须保证方法参数、返回值和父类方法一致,否则会出现逻辑不执行、请求报错的问题。如果只是加提示信息、做小范围逻辑调整,优先用父类提供的钩子方法,不要重复实现框架已经封装好的认证、校验逻辑,避免出现安全问题。
内容的提问来源于stack exchange,提问作者Nikola Nikolov
相关产品推荐
相关产品推荐

