Ajax技术+layer弹窗

一、Ajax技术简介

1、AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。

即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。

局部刷新、一步提交

2、作用

前端技术,把前端的数据提交到后端的。Ajax技术就是局部刷新,异步提交,它不需要刷新整个页面,只需要刷新局部的,主要就是刷新的时候是无感知的

3、案例

html 前端页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<input type="text" name="" id="d1">+
<input type="text" name="" id="d2">=
<input type="text" name="" id="d3">
<button class="btn btn-info">计算</button>
<script>
    $(".btn").click(function() {
        // 获取输入框中的内容
        var d1 = $("#d1").val();
        var d2 = $("#d2").val();

        // 前端数据提交到后端
        $.ajax({
            // 1、提交到哪里
            url: "",
            // 2、要指定请求方式提交
            type: "post",
            // 3、指定要传递的数据
            data: {'d1':d1,'d2':d2},
            // 4、回调函数, 接收后端返回的数据
            success : function(res){
                {#console.log(res);#}
                $("#d3").val(res)
            }
        })
    })
</script>

</body>
</html>

注意:Ajax 提交数据到后端的4个步骤

$.ajax({
        url:'/index/?a=1&b=2',
        type:'post',
        data:{'a':1, b:2}
        success:function(res) {
            # res:什么时候反序列化,什么时候不反序列化
            console.log(res.username)
            console.log(res.data.password)
        }
    })

$.ajax({ }) ajax的调用,

后端返回的数据给res,大多数情况下,后端返回的数据直接就是json格式,如果是json格式的,就不用反序列化了

如果返回的是JSON格式的字符串,就需要反序列化

后端视图函数:

def index(request):
    if request.method == 'POST':
        # 接收参数
        d1 = request.POST.get('d1')
        d2 = request.POST.get('d2')

        # 做运算
        d3 = int(d1) + int(d2)
        return HttpResponse(d3)  # 返回给res

    return render(request, 'index.html')

注意⚠️后端返回数据的多种情况:

第一种:

当后端返回的值 res为string类型时,即 return HttpResponse(d3)。前端html页面可以直接使用。

前端自行反序列化 JSON.parse()后可以改变类型,比如前端传来的d3是一个string,JSON.parse()后是number。

success : function(res){
                res = JSON.parse(res);
                console.log(res);
                console.log(res.code);
                {#$("#d3").val(res)#}
            }

没有反序列化:前端能直接使用后端传来的string数据

反序列化以后:反序列化之后依旧可以直接使用,数据类型变为number

第二种:

后端直接返回 JsonResponse()数据,前端不需要在反序列化,可以直接取值。

JsonResponse()返回的数据就是json数据

# 后端
from django.http  import JsonResponse

def index(request):
    if request.method == 'POST':
        d = {'code': 200, 'meg': '请求成功', 'data': {'username': 'jingzhi'}}
        return JsonResponse(d)

    return render(request, 'index.html')

# 前端
 $.ajax({
            // 1、提交到哪里
            url: "",
            // 2、要指定请求方式提交
            type: "post",
            // 3、指定要传递的数据
            data: {'d1':d1,'d2':d2},
            // 4、回调函数, 接收后端返回的数据
            success : function(res){
                console.log(res);
                console.log(res.code);
                console.log(res.meg);
            }
        })

 第三种: 

后端序列化后使用HttpResponse()方式,前端需要指定数据类型dataType: "json",

# 后端
def index(request):
    if request.method == 'POST':
        d = {'code': 200, 'meg': '请求成功', 'data': {'username': 'jingzhi'}}
        import json
        res = json.dumps(d, ensure_ascii=False)  # res序列化为字符串
        return HttpResponse(res)  # 返回给res

    return render(request, 'index.html')

# 前端
$.ajax({
            // 1、提交到哪里
            url: "",
            // 2、要指定请求方式提交
            type: "post",
            // 3、指定要传递的数据
            data: {'d1':d1,'d2':d2},
            dataType: "json",
            // 4、回调函数, 接收后端返回的数据
            success : function(res){
                console.log(res);
                console.log(res.code);
                console.log(res.meg);
            }
        })

二、Ajax提交json格式的数据

要满足的两个条件
1. 你传的数据一定要是json格式的
2. 一定要把ajax默认提交的urlencode改为'application/json'

1、html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<button class="btn btn-info">按钮</button>

<script>
    $(".btn").click(function () {
        $.ajax({
            url: '/index/',
            type: 'post',
            data: JSON.stringify({a1: 1, a2: 2}),
            contentType : 'application/json',
            success: function (res) {
                console.log(res)
            }
        })
    })
</script>
</body>
</html>

2、views

from django.shortcuts import render
import json

# Create your views here.
def index(request):
    print(request.body)  # b'{"a1":1,"a2":2}'
    json_str = json.loads(request.body)  # json.loads 能够自动进行二进制解码,然后再反序列化
    print(json_str.get('a1'))
    return render(request, 'index.html')

注意:

1.  针对ajax提交的json格式的数据,django后端不在把数据封装到request.POST中了。

2. 前端发送json数据的前提:数据进行序列化、指定内容类型

data: JSON.stringify({a1: 1, a2: 2}),
contentType : 'application/json',

3、后端拿到数据是纯原生的,发送过来的数据是二进制形式的,后端需要解码、反序列化 

三、Ajax提交文件数据(重要)

1、html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
</head>
<body>
<form action="">
    username: <input type="text" id="username">
    password: <input type="password" id="password">
    文件: <input type="file" id="my_file">
    <button class="btn btn-primary">提交</button>
 {# 两次提交,提交按钮可以放到form表单外#}
</form>

{#<button class="btn btn-info">按钮</button>#}

<script>
    $(".btn").click(function (event) {
        // 拿普通数据
        var username = $("#username").val();
        var password = $("#password").val();

        // 拿文件数据
        {#var my_file = $("#my_file");  {#产生一个jq对象,在浏览器控制台可以查看#}
        {#console.log(my_file);#}
        var myfile = $("#my_file")[0].files[0];
        {#console.log(myfile);#}

        // 发送文件数据到后端需要借助于FormData对象
        var myFormDataObj = new FormData();
        myFormDataObj.append('username', username);
        myFormDataObj.append('password', password);
        myFormDataObj.append('myfile', myfile);

        $.ajax({
            url: '/index/',
            type: 'post',
            data: myFormDataObj,
            contentType:false, // 告诉浏览器不要做任何的编码格式处理,django自己来做处理
            processData:false, // 告诉浏览器不要对我处理的数据做任何的处理
            success: function (res) {
                {#console.log(res)#}
            }
        });
        event.preventDefault(); {#阻止后续提交第一种方式#}
        {#return false #}   {#阻止后续提交第二种方式#}
    })
</script>
</body>
</html>

关于 var myfile = $("#my_file")[0].files[0]; 的补充

$("#my_file") 返回一个包含匹配元素的数组。由于我们只对一个元素感兴趣,通过 [0] 来获取这个元素。

.files[0]: 一旦我们有了文件输入字段元素,我们可以通过 .files 属性访问用户选择的文件列表。因为文件输入字段允许用户一次选择多个文件,这是一个文件列表。在这里,我们使用 [0] 来获取列表中的第一个文件。因此,$("#my_file")[0].files[0] 返回用户选择的第一个文件。

2、views

from django.shortcuts import render

# Create your views here.
def index(request):
    # print(request.body)  # b'{"a1":1,"a2":2}'
    # json_str = json.loads(request.body)  # json.loads 能够自动进行二进制解码,然后再反序列化
    # print(json_str.get('a1'))
    if request.method == 'POST':
        print(request.POST.get('username'))  # <QueryDict: {'username': ['DSAD'], 'password': ['DSADAS']}>
        print(request.FILES.get('myfile'))  # <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 462_001_afm_3600_5400.jpg (image/jpeg)>]}>

        file_obj = request.FILES.get('myfile')
        with open(file_obj.name, 'wb') as f:
            for line in file_obj:
                f.write(line)
    return render(request, 'index.html') 

四、AJax结合layer弹窗实现删除的二次确认

1、layer弹窗

layer 弹出层组件 - jQuery 弹出层插件 (layuiweb.com)

layui 颜色参考 - 页面元素 - Layui (layuiweb.com)

下载

引入static文件

<script src="/static/layer/layer.js"></script>

引用效果

2、html

{% extends 'home.html' %}

{% block content %}
    <h1 class="text-center">图书列表展示</h1>
    <a href="/book_add/" class="btn btn-info">添加图书</a>
    <table class="table  table-striped table-hover">
        <thead>
        <tr>
            <th>标题</th>
            <th>价格</th>
            <th>出版日期</th>
            <th>出版社</th>
            <th>作者</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        {% for foo in book_queryset %}
            <tr class="tr_{{  foo.pk }}">
                <td>{{ foo.title }}</td>
                <td>{{ foo.price }}</td>
                <td>{{ foo.publish_date|date:'Y-m-d' }}</td>
                <td>{{ foo.publish.name }}</td>
                {#书查出版社,正向查询,外键字段跳表#}
                <td>
                    {% for author in foo.authors.all %}
                        {% if forloop.last %}
                            {{ author.name }}
                        {% else %}
                            {{ author.name }} |
                        {% endif %}
                    {% endfor %}

                </td>
                <td>
                    {#                    <a href="/book/edit/{{ foo.pk }}" class="btn btn-success">修改</a>#}
                    <a href="/book_edit/?id={{ foo.pk }}" class="btn btn-success">修改</a>
                    <a href="#" class="del  btn btn-danger" delete_id="{{ foo.pk }}">删除</a>
                    {#这里不能使用id标签,因为在for循环中,id不能重复 自定义一个id,a标签自动跳转也相当于有二次提交#}
                </td>
            </tr>
        {% endfor %}

        </tbody>
    </table>
{% endblock %}

{% block js %}

    <script>
         $(".del").click(function () {
            // 删除的逻辑:当我们点击删除按钮的时候,应该获取点击行的id值,然后,把这个id传到后端,后端接收这个id值
            // 做删除逻辑
            var id = $(this).attr('delete_id');  {#这里的this代表的是$(".btn")对象#}
            var _this = $(this);
            // 紧接着要发送ajax请求,最好做一个二次确认
            layer.confirm('你确定要删除这条数据吗?', {
                btn: ['确定'] //按钮
            }, function () {
                // 发送ajax请求
                $.ajax({
                    url: '/book_del/',  // {# 把请求提交到del视图函数中去#}
                    type: 'post',
                    data: {id: id},
                    success: function (res) {
                        if (res.code == 200) {
                            {#layer.msg(res.msg, {icon:2}, function () {#}
                            {#    location.reload();}  {# ajax不会自动刷新页面 #}
                            layer.msg(res.msg);  {# 接收后端返回的信息 #}
                            _this.parent().parent().remove(); {# this 指的是function (res) _this引用变量 #}
                            {#$(".tr_" + id).remove();  删除dom的tr行来实现不展示#}
                        }
                    }
                });
            });
        })
    </script>
{% endblock %}

3、views

def book_del(request):
    del_id = request.POST.get('id')  # 这个id是 ajx传的 id = $(this).attr('delete_id');
    print(del_id)
    models.Book.objects.filter(pk=del_id).delete()
    # return redirect('/authors_list/') ajax发过来的数据,不需要页面跳转
    return JsonResponse({'code': 200, 'msg': '删除成功!'})  # 如果需要给前端返回数据+'data':{}

4、效果

五、Ajax 实操 

简易图书管理系统,前端通过Ajax传数据到后端

html

{% extends 'home.html' %}

{% block content %}
    <h1 class="text-center">修改作者</h1>
    <div class="container">
        <div class="row">
                <div class="form-group">
                    <input type="hidden" id="hidden_id" value="{{ author_obj.pk }}" name="hidden_id">
                    <div class="form-group">
                        作者名:<input type="text" id="name" class="form-control" name="name" value="{{ author_obj.name }}">
                    </div>
                </div>
                <div class="form-group">
                    年龄:<input type="text" id="age" class="form-control" name="age" value="{{ author_obj.age }}">
                </div>
                <div class="form-group">
                    phone:<input type="text" id="phone" class="form-control" name="phone"
                                 value="{{ author_obj.author.phone }}">
                </div>
                <div class="form-group">
                    addr:<input type="text" id="addr" class="form-control" name="addr"
                                value="{{ author_obj.author.addr }}">
                </div>
                <div class="form-group">
                    <input type="button" id="submitButton" class="btn btn-success btn-block" value="Submit">
                </div>
            <script>
                $("#submitButton").click(function () {
                    let id = $("#hidden_id").val();
                    let name = $("#name").val();
                    let age = $("#age").val();
                    let phone = $("#phone").val();
                    let addr = $("#addr").val();
                    console.log(id)
                    console.log(name)
                    $.ajax({
                        url: '/authors_edit/',
                        type: 'post',
                        data: {'id':id,'name': name, 'age': age, 'phone': phone, 'addr': addr},
                        success: function (res) {
                            // 这里可以添加一些成功后的处理逻辑
                            alert(res.msg);
                            window.location.href=res.url;
                        },
                        error: function (err) {
                            // 这里可以添加一些错误处理逻辑
                            alert("提交失败,请重试");
                        }
                    })
                })
            </script>
        </div>
    </div>
{% endblock %}

views

# 修改作者
def authors_edit(request):
    author_edit_id = request.GET.get('id')  # 先获取GET传参的id
    author_obj = models.Author.objects.filter(pk=author_edit_id).first()  # 获取一个publish_obj对象
    author_detail_obj = models.Author.objects.filter(pk=author_edit_id).first()  # 获取一个publish_obj对象
    if request.method == 'POST':
        new_id = request.POST.get('id')
        new_name = request.POST.get('name')
        new_age = request.POST.get('age')
        new_phone = request.POST.get('phone')
        new_addr = request.POST.get('addr')

        # 写入数据库
        models.Author.objects.filter(pk=new_id).update(name=new_name, age=new_age)
        models.Authordetail.objects.filter(author__pk=author_edit_id).update(phone=new_phone, addr=new_addr)

        res = {'url': '/authors_list/', 'code': 200, 'msg': '后端拿到数据!', 'data': {'username': new_name}}
        return JsonResponse(res)
    return render(request, 'authors_edit.html', locals())

  

 

 

 

 

12-Django与Ajax (yuque.com)

posted @ 2023-08-07 20:12  凡人半睁眼  阅读(137)  评论(0编辑  收藏  举报