10 django管理系统 - 管理员管理 - 新建管理员(通过模态框和ajax实现)

在文章"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">&times;</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">&times;</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">&times;</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发送请求完成的添加。

相关推荐
天人合一peng17 分钟前
20201010 MTAP-3DGAM审稿意见
后端·3d·restful
demodeom18 分钟前
Python 操作 读/写 Excel
服务器·python·excel
计算机学姐40 分钟前
基于SpringBoot的汽车票网上预订系统
java·vue.js·spring boot·后端·mysql·java-ee·mybatis
进步哥41 分钟前
python之爬虫遇到返回内容乱码
开发语言·爬虫·python
哎呦没1 小时前
农村扶贫管理:SpringBoot解决方案
java·spring boot·后端
萤火架构1 小时前
使用FastAPI整合Gradio和Django
django·fastapi·gradio
云天徽上1 小时前
【NLP-06】词形还原(Lemmatization)深度解析与实践
python·机器学习·自然语言处理
Nerinic1 小时前
Python基础10
python
白狐欧莱雅1 小时前
使用Python中的DrissonPage库爬取小说网站并保存章节内容(bqg)
经验分享·笔记·python·自动化·drissonpage
武子康1 小时前
大数据-197 数据挖掘 机器学习理论 - scikit-learn 泛化能力 交叉验证
大数据·人工智能·python·机器学习·数据挖掘·scikit-learn