Django实现登录弹窗无刷新显示账号密码错误信息
Django登录弹窗无刷新显示错误提示方案
核心思路
要实现不刷新页面展示错误提示,必须用AJAX异步提交表单:让前端通过JS发送请求,后端返回JSON格式的结果,前端根据结果动态更新页面内容,彻底避免表单默认提交导致的页面刷新。
步骤1:修改后端视图(views.py)
调整登录逻辑,使其支持AJAX请求并返回JSON数据:
from django.http import JsonResponse from django.contrib.auth import authenticate, login def main(request): form = CreateUserForm() context = {'form': form} if "register-btn" in request.POST: # 保留原注册逻辑 .... elif "login-btn" in request.POST: # 判断是否为AJAX请求 if request.headers.get('X-Requested-With') == 'XMLHttpRequest': username = request.POST.get('username-log') password = request.POST.get('password-log') user = authenticate(request, username=username, password=password) if user is not None: login(request, user) return JsonResponse({'status': 'success', 'redirect_url': '/account'}) else: return JsonResponse({'status': 'error', 'message': 'Username or password is incorrect'}) return render(request, 'accounts/main.html', context)
这里不再使用messages框架,因为AJAX请求不会触发模板渲染,直接返回JSON数据更适配异步场景。
步骤2:修改前端页面(main.html)
给表单添加标识、错误容器,并用JS处理异步提交:
<!-- 给表单添加ID,方便JS操作 --> <form id="login-form"> <label>Your login</label> <input name="username-log" class="form-control" type="text" placeholder="Enter your login"> <label>Password</label> <input name="password-log" class="form-control" type="password" placeholder="Enter your password"> <!-- 错误提示容器,初始隐藏 --> <p id="login-error" class="xerr" style="display: none;"></p> <button name="login-btn" class="btn btn_100" type="submit">LOG IN</button> </form> <script> document.getElementById('login-form').addEventListener('submit', function(e) { // 阻止表单默认提交行为(避免页面刷新) e.preventDefault(); // 组装表单数据,添加登录标识供后端判断 const formData = new FormData(this); formData.append('login-btn', ''); // 发送AJAX请求 fetch('{% url "main" %}', { // 替换为你main视图的URL名称 method: 'POST', headers: { 'X-CSRFToken': '{{ csrf_token }}', // Django必需的CSRF令牌 'X-Requested-With': 'XMLHttpRequest' // 告知后端是AJAX请求 }, body: formData }) .then(response => response.json()) .then(data => { if (data.status === 'success') { // 登录成功,跳转到目标页面 window.location.href = data.redirect_url; } else { // 显示错误信息 const errorEl = document.getElementById('login-error'); errorEl.textContent = data.message; errorEl.style.display = 'block'; // 可选:3秒后自动隐藏错误提示 setTimeout(() => { errorEl.style.display = 'none'; }, 3000); } }) .catch(error => { console.error('请求失败:', error); const errorEl = document.getElementById('login-error'); errorEl.textContent = '登录请求失败,请稍后重试'; errorEl.style.display = 'block'; }); }); </script>
注意事项:
- 确保你的
main视图在urls.py中设置了名称,比如path('', views.main, name='main'),这样{% url "main" %}才能正确生成请求地址。 - CSRF令牌必须携带,否则Django会拒绝POST请求。
内容的提问来源于stack exchange,提问作者Fors1t
相关产品推荐
相关产品推荐

