在文章"04 django管理系统 - 部门管理 - 新增部门"中,我们通过传统的新增页面来实现部门的添加。
在本文中,我们通过模态框和ajax来实现管理员的新增。
首先在admin_list.html中新建入口,使用按钮
html
<div class="panel-heading">
<input type="button" class="btn btn-primary" value="新建管理员">
</div>
效果如下:
我们希望点击【新建管理员】的时候,跳一个弹框出来。我们从bootstrap官网随便扒拉一个模态框例子即可。
那么就需要给按钮设置data-toggle和data-target属性以及id
html
<div style="margin-bottom: 18px">
<input type="button" class="btn btn-primary" value="新建管理员" data-toggle="modal"
data-target="#myModal" id="btn_add">
</div>
同时,要给即将弹出的框子赋予同样的属性
html
<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"><span
aria-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>
效果如下:
接下来就需要绑定点击事件了。
javascript
{% block js %}
<script>
// 绑定btn_add的点击事件
$(function () {
bingBtnAddEvent();
})
function bingBtnAddEvent() {
$("#btn_add").click(function () {
// 点击新建管理员,弹出模态框
console.log("click btn_add");
})
}
</script>
{% endblock %}
效果如下:
接着,就需要把表单填入弹框。
我们回到admin.py中,编辑业务逻辑
我们首先创建管理员的ModelForm
python
class AdminModelForm(BootStrapModelForm):
class Meta:
model = models.Admin
fields = "__all__"
接着去修改业务逻辑,看看能不能在前端接收到这个表格内容
1 我们创建form对象,并且传递到前端界面
python
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 我们在前端界面接收一下
html
<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"><span
aria-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
html
<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>
效果如下:
我们把标题和按钮的名称都改一下
html
<!-- 新建订单弹框 -->
<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"><span
aria-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
html
<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>
接着就是去绑定点击事件
javascript
<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悄咪咪的发送数据给后台
javascript
function bindBtnSaveEvent() {
$("#btn_save").click(function () {
{#alert("btn_save clicked! 我被点击拉")#}
// 下面是ajax提交表单数据,提交到后台
// 首先是批量获取表单数据
let formData = $("#formAdd").serialize();
console.log(formData);
})
}
可以看到确实有数据被console.log出来
接着就是发送请求了。
javascript
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/"
python
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()
python
def admin_add(request):
pass
因为ajax发送的是post请求,所以我们要免除csrf认证
python
@csrf_exempt
def admin_add(request):
pass
接下来就是数据校验部分了
python
@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里面去看看
javascript
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函数成功返回");
}
})
})
}
可以看到,被接收成功了
接着,我们去编写接收成功后的业务逻辑,添加成功后,自动刷新界面
javascript
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开头的,拼接字段。
既然如此,那么我们就遍历拼接。
javascript
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
html
<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>
效果如下:
并且,我们要在每次点击之前,先把错误信息清空。
javascript
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发送请求完成的添加。