django之ajax-sweetalert-contentType

Ajax

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

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

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。

AJAX 最大的优点:不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。这一特点给用户的感受是在不知不觉中完成请求和响应过程。

AJAX 的特点:异步提交、局部刷新

原生JS实现的Ajax过于复杂,实际项目中一般不用。

我们现在学习jQuery封装版本的Ajax,所以需要前端页面实现导入了jQuery模块。

其实并不时只有jQuery能够实现Ajax,其他框架或者模块也可以,原理都是一样的。

Ajax基本操作

通过一个小案例来介绍Ajax的基本使用

# 需求:
1.前端页面有2个输入框,1个输出框
2.在两个输入框中输入数字,点击按钮,第三个输出框显示两个数字之和。

前端页面,ajax提交post请求

<input type="text" id="d1"> +
<input type="text" id="d2"> =
<input type="text" id="d3">
<p><button id="cal-btn">计算</button></p>


<script>
    $('#cal-btn').click(function () {
        $.ajax({
            url:'',
            type:'post',
            data: {'d1': $('#d1').val(), 'd2': $('#d2').val()},
            success:function (args) {
                $('#d3').val(args)
            }
        })
    })
</script>


参数:
- url:		提供ajax请求的路由,可以有三种方式:全称/后缀/不写(默认当前页面的url)
- type:		指定ajax请求的方式,get/post, 默认是get请求
- data:		请求提供的数据,键值对的方式存放在自定义对象中
- success:	回调函数,当请求收到响应后自动触发执行。args是接收响应数据的形参。
- dataType: 扩展参数,dataType:'JSON', 表示希望接收json格式的数据

补充:当后端以HttpResponse返回的json格式的数据,默认是不会自动反序列化
- 1.手动序列化:JSON.stringify()
- 2.配置参数:dataType 结论:写ajax的时候直接将dataType参数加上,以防万一,或者后端就用JsonResonse

后端逻辑

from django.shortcuts import render, HttpResponse

def ajax_text(request):
    if request.method == 'GET':
        return render(request, 'ajax_text.html')

    d1 = request.POST.get('d1')
    d2 = request.POST.get('d2')
    d3 = int(d1) + int(d2)
    return HttpResponse(d3)

# ajax提交的post请求携带的普通数据依然通过request.POST获取。

ajax发送json格式数据

ajax向后端发送json数据需要注意两点:

  • 发送的数据必须是json格式的
  • 必须设置:contentType: 'application/json'

前端页面,ajax发送json数据

<script>
    $('#cal-btn').click(function () {
        $.ajax({
            url: '',
            type: 'post',
            data: JSON.stringify({'d1': $('#d1').val(), 'd2': $('#d2').val()}),
            contentType: 'application/json',  // 必须 指定编码格式
            success:function (args) {
                alert(typeof args);
                $('#d3').val(args)
            }
        })
    })
</script>

ajax通过post请求提交的json格式数据,django不会再帮忙封装到request.POST中,需要手动到request.body中反序列化获取。

def ajax_json(request):
    if request.is_ajax():
        if request.method == 'POST':
            request_dict = json.loads(request.body)
            d1 = request_dict.get('d1')
            d2 = request_dict.get('d2')
            d3 = int(d1) + int(d2)
            return HttpResponse(d3)

    if request.method == 'GET':
        return render(request, 'ajax_json.html')

补充总结

  • request.is_ajax()可以用来判断请求是否为ajax请求,返回布尔值。
  • 接收ajax的post方式提交的json数据将会原封不动的保存在request.body中,并且是二进制格式数据。从中获取数据需要分两步操作:解码、反序列化。使用的工具是json模块提供的loads()方法。
# 方式1:分两步
request_str = request.body.decode('utf-8')		# 解码
request_dict = json.loads(request_str)			# 反序列化

# 方式2:一步到位
request_dict = json.loads(request.body)			# 利用loads()的自动解码功能

ajax发送文件

ajax发送文件需要借助于js内置对象FormData

将文件数据和其他普通键值对数据封装到FormData对象中

并且,还需要使用两个参数:contentTypeprocessData

<script>
    $('#btn-submit').click(function () {
        
        let formDataObj = new FormData();		// 将普通数据和文件添加到该对象中
        formDataObj.append('username', $('#username').val());
        formDataObj.append('avatar', $('#avatar')[0].files[0]);

        $.ajax({
            url: '',
            type: 'post',
            data: formDataObj,
            contentType: false,  			// 必须的
            processData: false,	 			// 必须的
            success: function (args) {
                alert(args)
            }
        })
    })
</script>

参数设置:
- contentType: false	告诉浏览器不要任何编码,django后端能够自动识别formdata对象
- processData: false	告诉浏览器不要对数据做任何处理	

补充:
- jquery获取文件方式:$('#avatar')[0].files[0], jquert对象转js对象再取文件对象
- django后端能够直接识别formdata对象,并且能够将内部的普通键值自动解析并封装到request.POST中;文件数据自动解析并封装到request.FILES中

编码格式contentType

get请求携带的数据是直接放在url后面的,如

book_list/?page_id=1&delete_book_id=2

目前朝后端提交post请求的方式有2种

form表单		# 参数:method='post'
ajax请求		# 参数:type='post'

# 两者默认的提交方式都是get请求

前后端传输数据的编码格式:

urlencoded		# 默认是 urlencoded
formdata		# 传文件必须使用formdata
json

form表单提交post请求的编码格式

form表单默认使用的编码格式是urlencoded,可以通过参数enctype修改编码格式

# post提交数据采用的编码格式为:urlencoded
此时数据的格式为:username=the3times&password=123
django后端针对符合urlencoded编码格式的数据都会自动帮你解析封装到request.POST中


# post提交数据采用的编码格式为:formdata
此时django将普通的键值对数据依然封装到request.POST中, 文件数据封装到request.FILES中


# post表单请求无法发送json格式数据

Ajax提交post请求的编码格式

ajax默认使用的编码格式也是urlencoded,可以通过参数contentType修改编码格式

# ajax提交数据采用的编码格式为:urlencoded
此时数据的格式为:username=the3times&password=123
django后端针对符合urlencoded编码格式的数据都会自动帮你解析封装到request.POST中


# ajax提交数据采用的编码格式为:formdata
# 借助js的FormData对象,将普通数据和文件数据都可以封装到该对象中再传给后端
此时django将普通的键值对数据依然封装到request.POST中, 文件数据封装到request.FILES中

let formDataObj = new FormData();
formDataObj.append('username', $('#username').val());
formDataObj.append('avatar', $('#avatar')[0].files[0]);

$.ajax({
    url: '',
    type: 'post',
    data: formDataObj,
    contentType: false,  // 不需使用任何编码 django后端能够自动识别formdata对象
    processData: false,
    success: function (args) {
        alert(args)
    }
})


# ajax提交数据采用的编码格式为:json
此时数据原封不动的存放在request.body中,需要将二进制数据解码后再反序列化,获取其中的数据

$.ajax({
    url: '',
    type: 'get',
    data: JSON.stringify({'d1': $('#d1').val(), 'd2': $('#d2').val()}),
    contentType: 'application/json',  // 指定编码格式
    success:function (args) {
        alert(typeof args);
        $('#d3').val(args)
    }
})

ajax结合sweetalert插件

ajax结合sweetaler插件实现删除数据的二次确认操作。

下载插件

  • 将压缩包解压,直接将里面的dist文件夹拷贝粘贴到项目的静态数据文件夹中,通过link标签和script标签将其中的css文件和js文件加载到需要的html页面上。

使用插件

  • 选择该网站中需要的弹出框形式,复制js代码,并修改。

案例介绍

ajax结合sweetalert实现图书管理页面书籍的删除二次确认操作。想看完整项目你就点一下

前端页面

{% for book_obj in book_queryset %}
	<tr>
        <td class="text-center">
        	<button class="btn btn-xs btn-danger btn-delete" delete_id="{{ book_obj.pk }}">删除</button>
        </td>
    </tr>
{% endfor %}


<script>
$('.btn-delete').click(function () {
        let currentBtn = $(this);       // 必须放着这个位置(当前点击的this),不要放在 		if(isConfirm)里面了
        swal({
            title: "确定删除?",
            text: "删除后将就找不回来了!",
            type: "warning",
            showCancelButton: true,
            confirmButtonClass: "btn-danger",
            confirmButtonText: "确定,删了它",
            cancelButtonText: "算不吧,不删了!",
            closeOnConfirm: false,
            closeOnCancel: false,
            // showLoaderOnConfirm: true, 增加该参数可以实现网络IO的等待效果
        },
        function(isConfirm) {
            if (isConfirm) {
                $.ajax({
                    url: '{% url "book_delete" %}',
                    type: 'post',
                    data: {'delete_id': currentBtn.attr('delete_id')},
                    success: function (args) {
                        if (args.status_code === 1111){
                            currentBtn.parent().parent().remove();
                            swal("删除成功!", args.msg, "success");
                        }else {
                            swal("删除失败!", args.msg, "success");
                        }
                    }
              });
              }else {
                    swal("取消操作", "没有删除该书籍 :)", "error");
                }
            });
})
</script>

# 关键点有两个位置:
第4行代码,每个标签添加一个属性,属性值是当前图书的主键值,为了确定删除的是哪一本书
第12行代码,这个this一定要更在点击事件之后,表示当前点击的是那个按钮,这样在30行可以方便的取出表示书籍的主键值
第33行代码,通过DOM操作将该行数据从文档节点中删除,实现页面的动态效果,用户体验度好。

后端逻辑视图函数

from django.http import JsonResponse
from app01 import models


def book_delete(request):
    back_msg = {'status_code': 1111, 'msg': ''}
    try:
        delete_id = request.POST.get('delete_id')
        models.Book.objects.filter(pk=delete_id).delete()
        back_msg['msg'] = '删除成功'
    except:
        back_msg['status_code'] = 2222
        back_msg['msg'] = '删除失败'
    # 级联删除
    return JsonResponse(back_msg)		# 返回JsonResponse对象,自动序列化且前端自动反序列化
posted @ 2020-06-03 18:09  the3times  阅读(154)  评论(0编辑  收藏  举报