ajax


一、Ajax

'''页面不刷新的情况下可以与后端进行数据交互
    异步提交 局部刷新
eg:码云用户注册 无序点击按钮内部也可以完成数据交互
    
ajax不是一门全新知识 本质就是一些js代码 我们学习ajax直接使用jQuery封装之后的版本(语法更简单)    使用ajax的前提必须要引入jQuery文件'''

# ajax和form的区别
    ajax提交数据页面不用刷新 原始数据还在 处理数据的过程中不影响页面其他操作
    form表单提交数据页面刷新 原始数据不在 并且处理数据的过程中无法做其他操作

1.代码实现

'''eg:页面上放三个input框 前面两个输入数字 第三个计算两个数字的和  按完按钮之后页面不能刷新 而且框中的数字不能消失'''

# form表单是实现不了的, form表单已提交就会直接刷新页面

$('#btn').click(function (){  # 给按钮绑定点击事件
         # 获取两个框里面的数据
        let i1Val = $('#i1').val();
        let i2Val = $('#i2').val();
        # 发送ajax请求传输数据
        $.ajax({
            url:'',  # 不写默认就是当前页面所在的地址
            type:'post',  # 指定当前请求方式  
            data:{'i1':i1Val,'i2':i2Val},  # 请求携带的数据  后端通过K获取值
            success:function (arg){  # 异步回调函数 后端有回复自动触发
                $('#i3').val(arg)   
            }
        })
    })
# 这样就可以在页面实现不刷新 给后端提交数据

2.基础语法

$.ajax({
    url:'',  # 控制数据的提交地址  不写就是默认给当前地址提交
    type:'',  # 控制请求方式(默认get请求)
    data:{},  # 组织提交的数据  后端按照K取值
    success:function(形参){  # 形参就是接收后端返回的值
            # 异步回调函数 可以根据后端返回的值操作
    }
})

二、数据编码格式

# 当我们进行前后端文件传输的时候是依据数据的编码格式的

# form表单修改编码格式的属性为:enctype
# ajax修改编码格式的属性为:Content-Type

'''
请求体中携带编码方式
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
django针对不同编码方式对应的数据格式会采用不同的处理策略
'''

# form表单默认发送的编码格式:
    Content-Type: application/x-www-form-urlencoded
    数据格式:username=jason&password=123
    django后端会自动处理到:request.POST
# form表单发送文件
    Content-Type:multipart/form-data
    数据格式:隐藏了不让看
    django后端会自动处理:request.POST  request.FILES
# ajax默认的编码格式
    Content-Type: application/x-www-form-urlencoded
    数据格式:username=jason&password=123
    django后端会自动处理到:request.POST

'''ajax和form表单默认的编码格式都是urlencoded
form表单发送文件需要把编码格式修改为 multipart/form-data
form表单不能传输json格式数据  需要使用ajax
'''

三、ajax携带文件数据

# form表单发送文件数据就只需要把编码格式修改为 multipart/form-data 那ajax怎么携带文件数据呢?

# 前端
$('#d3').click(function () {
        # 产生一个对象
        let formData = new FormData()
        # 添加普通数据
        formData.append('username',$('#d2').val())
        # 添加文件数据
        formData.append('file',$('#d1')[0].files[0]) # 后端就是根据前面字符串提取数据  第一个索引变成标签对象 如果是多个文件第二个索引可以不用加
        $.ajax({
            url:'',
            type:'post',
            data:formData,
            #  添加文件数据需要写两个固定参数
            contentType:false,  # 不用任何编码
            processData: false,  # 不处理数据对象
            success:function (args){

            }
        })
    })
# 后端
    username = request.POST.get('username')
    file = request.FILES.get('file')
# 后端还是一样的

四、ajax发送json格式数据

# 前后端交互数据一般都是使用json格式数据 form表单是发送不了json格式数据的 只能使用ajax

# 前端:
    $('#d1').click(function (){
            $.ajax({
            url: '',
            type: 'post', # 不写默认是get请求
            contentType:'application/json', # 不写默认是urlencoded编码
            data: JSON.stringify({'name': 'jason', 'pwd': 123}),  # 直接发送json格式数据
            success: function (args) {
            }
            })
    })
# 后端:
'''django后端针对json格式的数据不会做任何的处理 就在request.body内
需要我们自行处理'''

print(request.POST, request.FILES)  # <QueryDict: {}> <MultiValueDict: {}>
# 所以POST和FILES是拿不到前端发送过来的json格式数据的
# 需要在request.body中获取
        print(request.body)  # b'{"name":"jason","pwd":123}' 是bytes类型
        data_json = request.body
        data = json.loads(data_json)  # json自带解码功能
        print(data, type(data))  # {'name': 'jason', 'pwd': 123} <class 'dict'>

五、回调函数

# 后端跟ajax交互 不应该再返回一个页面 而是返回一个json格式数据

# 向我们之前学习的三板斧render、redirect、HttpResponse

前两者都是返回一个页面 这样就算返回了前端也不会跳转
HttpResponse返回一个字符串其实也会被回调函数的参数接收

# 现在我们在后端发送给前端json格式数据 
# 后端
return HttpResponse(json.dumps({'name': 'jason', 'pwd': 123}))
# 前端
console.log(args)  # {"name": "jason", "pwd": 123}
console.log(typeof args) # string
# 我们发现后端发送过来的json格式数据是不会帮我们反序列化的

success: function (args) {
    let Data = JSON.parse(args)  # 需要我们手动反序列化
    console.log(typeof Data)  # object
    console.log(Data)  # {name: 'jason', pwd: 123}
    console.log(Data.name)  # jason
            }

# 但是这是使用HttpResponse返回的 现在我们使用JsonResponse返回看看
# 后端
return JsonResponse({'name': 'jason', 'pwd': 123})
# 前端
success: function (args) {
   console.log(typeof args) # object
   console.log(args)  # {name: 'jason', pwd: 123}
    console.log(args.name)  # jason
            }
'''
使用JsonResponse返回数据前端是会自动帮我们反序列化的 因为HttpResponse返回的其实就是一个字符串对象 前端所以不会反序列化 而JsonResponse返回的是一个json格式数据 前端就会帮我们自动反序列化 而如果想让HttpResponse自动反序列化需要加一个参数 dataType:'JSON' dataType:'JSON', success: function (args) { console.log(typeof args) // object console.log(args) // {name: 'jason', pwd: 123} console.log(args.name) // jason } '''

六、序列化

# 当我们以后前后端分离会后 前端是不识别 django ORM产生的Queryset数据对象的  所以还是需要json格式数据

# 后端:
data_list = []  # 数据格式为 [{}, {}, {}]
user_queryset = models.Book.objects.filter()
for obj in user_queryset:
    data_dict = {}
    data_dict['pk'] = obj.pk
    data_dict['title'] = obj.title
    data_dict['publish'] = obj.publish.name
    data_list.append(data_dict)
return HttpResponse(json.dumps(data_list))
# 这样有点代码冗余    django自带了序列化组件

# 后端:
from django.core import serializers
user_list = models.Book.objects.filter()
res = serializers.serialize('json', user_list)  # 第一个参数决定以什么方式序列化数据
return HttpResponse(res)

# 可以去bejson官网看下我们发送给前端的json格式的数据张啥样 这就是以后如果前后端分离 我们需要发送给前端的json格式数据

 七、作业

# 使用sweetalert做删除二次确认
后端:
def delete(request):
    if request.method == 'POST':
        data_id = request.POST.get('delete_id')
        models.Book.objects.filter(pk=data_id).delete()
    return HttpResponse('删除成功')

# 前端
<a href="#" class="btn btn-danger btn-xs subBtn" delete_id = {{ book_obj.id }}>删除</a>
        $('.subBtn').click(function (){
            let dataEle = $(this).attr('delete_id') # 获取删除的书籍id
            swal({
              title: "你确定要删除把",
              text: "你在想想吧",
              icon: "warning",
              buttons: ['取消', '确定'],
              dangerMode: true,
            })
            .then((willDelete) => {
              if (willDelete) {
                  $.ajax({
                      url:'/delete/',  # 朝删除网址发送
                      type:'post',
                      data:{'delete_id':dataEle},
                      success:function (args){
                            swal(args, {icon: "success",})
                      }
                  })
              } else {
                swal("不删就好");
              }
            });
        })

 

posted @ 2022-09-07 17:59  stephen_hao  阅读(64)  评论(0编辑  收藏  举报