在文章“04 django管理系统 - 部门管理 - 新增部门”中,我们通过传统的新增页面来实现部门的添加。
在本文中,我们通过模态框和ajax来实现管理员的新增。
首先在admin_list.html中新建入口,使用按钮
<div class="panel-heading"><input type="button" class="btn btn-primary" value="新建管理员">
</div>
效果如下:
我们希望点击【新建管理员】的时候,跳一个弹框出来。我们从bootstrap官网随便扒拉一个模态框例子即可。
那么就需要给按钮设置data-toggle和data-target属性以及id
<div style="margin-bottom: 18px"><input type="button" class="btn btn-primary" value="新建管理员" data-toggle="modal"data-target="#myModal" id="btn_add">
</div>
同时,要给即将弹出的框子赋予同样的属性
<div>
<!-- 新建订单弹框 --><div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal"aria-label="Close"><spanaria-hidden="true">×</span></button><h4 class="modal-title" id="myModalLabel">我是被弹出来的对话框</h4></div><div class="modal-body">我是弹出来的内容1我是弹出来的内容2我是弹出来的内容3我是弹出来的内容4</div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button><button type="button" class="btn btn-primary">Save changes</button></div></div></div></div>
</div>
效果如下:
接下来就需要绑定点击事件了。
{% block js %}<script>// 绑定btn_add的点击事件$(function () {bingBtnAddEvent();})function bingBtnAddEvent() {$("#btn_add").click(function () {// 点击新建管理员,弹出模态框console.log("click btn_add");})}</script>
{% endblock %}
效果如下:
接着,就需要把表单填入弹框。
我们回到admin.py中,编辑业务逻辑
我们首先创建管理员的ModelForm
class AdminModelForm(BootStrapModelForm):class Meta:model = models.Adminfields = "__all__"
接着去修改业务逻辑,看看能不能在前端接收到这个表格内容
1 我们创建form对象,并且传递到前端界面
def admin_list(request):# return HttpResponse("admin_list is ok")# 查询所有的数据queryset = models.Admin.objects.using("default").all()form = AdminModelForm()context = {"queryset": queryset,"form": form}return render(request, 'admin_list.html', context)
2 我们在前端界面接收一下
<div><!-- 新建订单弹框 --><div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal"aria-label="Close"><spanaria-hidden="true">×</span></button><h4 class="modal-title" id="myModalLabel">我是被弹出来的对话框</h4></div><div class="modal-body">{{ form }}</div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">Close</button><button type="button" class="btn btn-primary">Save changes</button></div></div></div></div>
</div>
就是我箭头指向的部分
效果如下:
为了后面方便操作表单以及美化界面,我们把这个div装饰一下,给个id
<div class="modal-body"><form id="formAdd"><div class="clearfix">{% for field in form %}<div class="col-xs-12"><div class="form-group"style="position: relative;margin-bottom: 20px;"><label>{{ field.label }}</label>{{ field }}<span class="error-msg"style="color: red;position: absolute;"></span></div></div>{% endfor %}</div></form>
</div>
效果如下:
我们把标题和按钮的名称都改一下
<!-- 新建订单弹框 -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"><div class="modal-dialog" role="document"><div class="modal-content"><div class="modal-header"><button type="button" class="close" data-dismiss="modal"aria-label="Close"><spanaria-hidden="true">×</span></button><h4 class="modal-title" id="myModalLabel">新建管理员</h4></div><div class="modal-body"><form id="formAdd"><div class="clearfix">{% for field in form %}<div class="col-xs-12"><div class="form-group"style="position: relative;margin-bottom: 20px;"><label>{{ field.label }}</label>{{ field }}<span class="error-msg"style="color: red;position: absolute;"></span></div></div>{% endfor %}</div></form></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">取消</button><button type="button" class="btn btn-primary">保存</button></div></div></div>
</div>
ok,现在,显示界面就出来了,接下来的工作就是,当用户点击保存的时候,就把表单中的数据插入到数据库中去。
首先就是要分配id:btn_save
<div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">取消</button><button type="button" class="btn btn-primary" id="btn_save">保存</button>
</div>
接着就是去绑定点击事件
<script>// 绑定btn_add的点击事件$(function () {// 新增按钮的点击事件bingBtnAddEvent();// 保存按钮的点击事件bindBtnSaveEvent();})function bingBtnAddEvent() {$("#btn_add").click(function () {// 点击新建管理员,弹出模态框console.log("click btn_add");})}function bindBtnSaveEvent() {$("#btn_save").click(function () {alert("btn_save clicked! 我被点击拉")})}
</script>
效果如下:
ok,可以看到,确实是点击成功了。
那么,接下来,我们就需要使用ajax悄咪咪的发送数据给后台
function bindBtnSaveEvent() {$("#btn_save").click(function () {{#alert("btn_save clicked! 我被点击拉")#}// 下面是ajax提交表单数据,提交到后台// 首先是批量获取表单数据let formData = $("#formAdd").serialize();console.log(formData);})
}
可以看到确实有数据被console.log出来
接着就是发送请求了。
function bindBtnSaveEvent() {$("#btn_save").click(function () {{#alert("btn_save clicked! 我被点击拉")#}// 下面是ajax提交表单数据,提交到后台// 首先是批量获取表单数据let formData = $("#formAdd").serialize();console.log(formData);// 发送ajax请求$.ajax({url: "/admin/add/",type: "post",data: formData,success: function (data) {console.log(data);}})})
}
然后去配置url路径: url: "/admin/add/"
urlpatterns = [# 部门管理path("dept/list/", dept.dept_list),path("dept/add/", dept.dept_add),path("dept/<int:nid>/edit_detail/", dept.dept_editdetail),path("dept/<int:nid>/delete/", dept.dept_delete),path("dept/search/", dept.dept_search),# 管理员管理path("admin/list/", admin.admin_list),path("admin/add/", admin.admin_add),]
去admin.py里去定义函数admin_add()
def admin_add(request):pass
因为ajax发送的是post请求,所以我们要免除csrf认证
@csrf_exempt
def admin_add(request):pass
接下来就是数据校验部分了
@csrf_exempt
def admin_add(request):"""处理管理员添加请求,该函数主要用于接收POST请求数据,并使用AdminModelForm进行数据验证和保存。通过Ajax方式提交请求时,服务器需要返回JsonResponse以提供异步处理结果。参数:- request: HttpRequest对象,包含了请求的相关信息,如POST数据。返回:- 若表单验证成功,返回包含'status': True的JsonResponse,表示添加成功。- 若表单验证失败,返回包含'status': False和错误信息的JsonResponse,表示添加失败。"""# 首先获取数据form = AdminModelForm(request.POST)if form.is_valid(): # 如果验证成功form.save()return JsonResponse({'status': 'True'})return JsonResponse({ # 如果验证失败'status': 'False','error': form.errors})
现在我们去前端ajax的success里面去看看
function bindBtnSaveEvent() {$("#btn_save").click(function () {{#alert("btn_save clicked! 我被点击拉")#}// 下面是ajax提交表单数据,提交到后台// 首先是批量获取表单数据let formData = $("#formAdd").serialize();console.log(formData);// 发送ajax请求$.ajax({url: "/admin/add/",type: "post",data: formData,success: function (data) {console.log(data,"我从admin_add函数成功返回");}})})
}
可以看到,被接收成功了
接着,我们去编写接收成功后的业务逻辑,添加成功后,自动刷新界面
function bindBtnSaveEvent() {$("#btn_save").click(function () {{#alert("btn_save clicked! 我被点击拉")#}// 下面是ajax提交表单数据,提交到后台// 首先是批量获取表单数据let formData = $("#formAdd").serialize();console.log(formData);// 发送ajax请求$.ajax({url: "/admin/add/",type: "post",data: formData,dataType: "json",success: function (data) {console.log(data, "我从admin_add函数成功返回");if (data.status === "True") {alert("添加成功!")window.location.reload();} else {alert("添加失败!")}}})})
}
我们来看看添加失败的情况
1 假设,我什么都不填,我看看啥情况
可以看到状态status的值是false,同时提示添加失败。
2 假设,我填写部分,我看看啥情况
可以看到,填写部分或者不填,是会弹窗的。
但是我们应该在界面上提示用户。ok,所以我们修改界面逻辑。
首先我们看看定位:
我们可以看到,输入框都是由id开头的,拼接字段。
既然如此,那么我们就遍历拼接。
function bindBtnSaveEvent() {$("#btn_save").click(function () {{#alert("btn_save clicked! 我被点击拉")#}// 下面是ajax提交表单数据,提交到后台// 首先是批量获取表单数据let formData = $("#formAdd").serialize();console.log(formData);// 发送ajax请求$.ajax({url: "/admin/add/",type: "post",data: formData,dataType: "json",success: function (data) {console.log(data, "我从admin_add函数成功返回");if (data.status === "True") {alert("添加成功!")window.location.reload();} else {alert("添加失败!")// 在弹出框中显示错误信息console.log(data.error);// 把错误信息显示在模态框中$.each(data.error, function (name, error_list) { // name就是字段名,error_list就是错误信息列表// 根据字段名字,找到对应的input标签,然后显示错误信息$("#id_" + name).next().text(error_list[0]);})}}})})
}
在form表单中,添加span
<form id="formAdd"><div class="clearfix">{% for field in form %}<div class="col-xs-12"><div class="form-group"style="position: relative;margin-bottom: 20px;"><label>{{ field.label }}</label>{{ field }}<span class="error-msg"style="color: red;position: absolute;"></span></div></div>{% endfor %}</div>
</form>
效果如下:
并且,我们要在每次点击之前,先把错误信息清空。
function bindBtnSaveEvent() {// 点击之前,清除错误信息$(".error-msg").empty()$("#btn_save").click(function () {{#alert("btn_save clicked! 我被点击拉")#}// 下面是ajax提交表单数据,提交到后台// 首先是批量获取表单数据let formData = $("#formAdd").serialize();console.log(formData);// 发送ajax请求$.ajax({url: "/admin/add/",type: "post",data: formData,dataType: "json",success: function (data) {console.log(data, "我从admin_add函数成功返回");if (data.status === "True") {alert("添加成功!")window.location.reload();} else {alert("添加失败!")// 在弹出框中显示错误信息console.log(data.error);// 把错误信息显示在模态框中$.each(data.error, function (name, error_list) { // name就是字段名,error_list就是错误信息列表// 根据字段名字,找到对应的input标签,然后显示错误信息$("#id_" + name).next().text(error_list[0]);})}}})})
}
自此,我们完成了添加管理员,并且是通过弹框以及ajax发送请求完成的添加。