如何在Django中基于Ajax和Bootstrap实现修改密码模态框表单
问题核心修复方案
你遇到的所有问题都可以通过以下4步修改解决:
1. 修正PasswordChangeView逻辑
把urls.py里的视图代码替换为以下内容,同时处理表单加载、提交成功、提交失败三种场景,避免修改密码后登出问题:
from django.http import JsonResponse from django.contrib.auth import update_session_auth_hash from django.contrib.auth.mixins import SuccessMessageMixin from django.contrib.auth.views import PasswordChangeView as AuthPasswordChangeView from django.urls import reverse class PasswordChangeView(SuccessMessageMixin, AuthPasswordChangeView): success_message = "Your password have been changed successfully." template_name = "password_change_form.html" def get_success_url(self): return reverse('export:index') def form_valid(self, form): self.object = form.save() # 保留session更新逻辑,避免用户登出 update_session_auth_hash(self.request, self.object) # 判断是ajax请求就返回json,否则走正常跳转 if self.request.headers.get('x-requested-with') == 'XMLHttpRequest': return JsonResponse({'status': 'success', 'msg': self.success_message}, status=200) return super().form_valid(form) def form_invalid(self, form): # 校验失败的时候返回带错误信息的表单 if self.request.headers.get('x-requested-with') == 'XMLHttpRequest': return self.render_to_response(self.get_context_data(form=form)) return super().form_invalid(form)
2. 修复password_change_form.html的语法错误
你的模板里有两个致命错误:嵌套了两层form标签、id重复(div和form都用了password_change作为id),替换为以下内容:
{% load bootstrap4 %} <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class='card' style="border-top-width: 0px;border-left-width: 0px;border-bottom-width: 0px;border-right-width: 0px;"> <div style="background-color:#326690;padding:5px 5px 5px 16px;color:white;font-weight:bold;border-radius: 2px 2px 0 0;">Change password</div> <form action="{% url 'registration:password_change' %}" method="post" id="password_change_form" class="form"> {% csrf_token %} <div class='card-body' style="padding-bottom:0px"> {% bootstrap_form form layout="horizontal" placeholder="None" size="medium" label_class="form-label col-md-3" %} </div> <hr style="margin:1px"> <div class='card-body' style="padding-top:5px;padding-bottom:5px;"> <div> <button type="submit" class="btn block" style="float:right;background-color:#326690;color:white;min-width:110px;">{% trans 'Confirm' %}</button> <span data-dismiss="modal" class="btn btn-light border" style="float:right;color:#326690;min-width:110px;margin-right:5px;"><i class="fa fa-times" aria-hidden="true"></i> {% trans 'Cancel' %}</span> </div> </div> </form> </div> </div> </div> <script> var form_options = { target: '#modal', success: function(response) { // 判断提交结果是成功的json还是带错误的表单 if (response.status && response.status === 'success') { // 手动关闭模态框,清除遮罩层 $('#modal').modal('hide'); $('body').removeClass('modal-open'); $('.modal-backdrop').remove(); // 展示成功提示 $("#password_change_confirm").append('<div class="alert alert-success"><button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button><span>'+ response.msg +'</span></div>'); } } }; $('#password_change_form').ajaxForm(form_options); </script>
3. 修正base.html的模态框触发逻辑
Bootstrap的data-toggle="modal"默认不会自动加载链接内容到模态框,你需要额外加一段js处理点击事件,把表单内容加载到模态框里:
<a class="dropdown-item" href="javascript:void(0)" id="change_pwd_btn"> <i class="fa fa-key" aria-hidden="true"></i> {% trans 'Change password' %} </a> <div class="modal fade" id="modal" tabindex="-1" role="dialog" aria-hidden="true"></div> <!-- 加这段js处理模态框加载 --> <script> $('#change_pwd_btn').click(function(){ $.get("{% url 'registration:password_change' %}", function(data){ $('#modal').html(data).modal('show'); }); }); </script>
4. 确认index.html逻辑
你现有的index.html代码不需要修改,已经可以正常展示提示信息。
以上修改覆盖了你遇到的所有问题:表单加载报错、灰屏不消失、修改密码后刷新登出、错误提交也弹成功提示。
内容的提问来源于stack exchange,提问作者Mereva
相关产品推荐
相关产品推荐

