zoukankan      html  css  js  c++  java
  • Django与Ajax

    Django与ajax(入门)

    AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步JavaScript和XML”。是指一种创建交互式,快速动态网页应用的网页开发技术,无需重新加载整个网页的情况下,能够更新部分网页的技术。

    通过在后台与服务器进行少量数据交换,AJAX可以使网页实现异步更新,这意味着在不重新加载整个网页页面的情况下,对网页的部分内容进行更新

    AJAX是一种用于快速动态网页的技术

    传统的网页(不使用AJAX)如果需要更新内容,必须重新加载整个页面,而前面谈到AJAX是什么,其主要就是异步提交,那我们来聊聊同步和异步提交的区别

    同步提交:当用户发送请求时,当前页面不可以使用,服务器响应页面到客户端,响应完成,客户才可以使用网页

    异步提交:当用户发送请求时,当前页面可以继续使用,当异步请求的数据响应给页面,页面把数据显示出来

    AJAX的工作原理:

    相当于在用户和服务器之间加了一个中间层(AJAX引擎),使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器,像一些数据验证和数据处理等都交给ajax引擎自己来做,只有确定需要从服务器读取数据时再由AJAX引擎代为向服务器提交请求

    客户端发送请求,请求交给xhr,xhr把请求提交给服务,服务器进行业务处理,服务器响应数据交给xhr对象,xhr对象接收数据,由javascript把数据写到页面上,如下图所示:

    要完整实现一个AJAX异步调用和局部刷新,通常需要以下几个步骤:

    1.创建XMLHttpRequest对象,即创建一个异步调用对象.
    2.创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
    3.设置响应HTTP请求状态变化的函数.
    4.发送HTTP请求.
    5.获取异步调用返回的数据.
    6.使用JavaScript和DOM实现局部刷新.

    ps:AJAX传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)
      基本上web页面都有很多ajax请求

    写ajax跟后端交互

    1 使用原生js写ajax请求(没有人用)
         第一:麻烦
         第二:区分浏览器,需要做浏览器兼容
    2 现在主流做法(现成有人封装好了,jquery,axios..)
        以jquery为例

    通过Ajax,实现前端输入两个数字,服务器做加法,返回到前端页面

    def ajax_test(request):
    
        return render(request,'ajax_test.html')
    
    
    def sum(request):
        import time
        time.sleep(2)
        # 先转成整型再加
        a1=int(request.GET.get('a1')) 
        a2=int(request.GET.get('a2'))
        return HttpResponse(a1+a2)
    视图函数views.py
    urlpatterns = [
         url(r'^ajax_test/',views.ajax_test),
        url(r'^sum/',views.sum),
    ]
    路由urls.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'JQuery3.6.0.js' %}"></script>
    
    </head>
    <body>
    <input type="text" id="a1"> + <input type="text" id="a2">=<input type="text" id="sum">
    <button id="btn_submit">计算</button>
    
    </body>
    <script>
        $('#btn_submit').click(function () {
            var a1 = $('#a1').val()
            var a2 = $('#a2').val()
            // 发送ajax请求,计算,返回结果
            $.ajax({
                url: '/sum/',  //ajax请求的地址
                method: 'get',//请求方式
                data: {'a1': a1, 'a2': a2}, //携带参数
                success: function (data) {   //服务端成功返回会回调,执行匿名函数
                    console.log(data)
                    $('#sum').val(data)
                }
            })
    
        })
    
    </script>
    </html>
    ajax_test.html

    1 ajax发送其他请求

    1 大坑
        如果在form表单中,写button和input是submit类型,会触发form表单的提交
        如果不想触发:
            不写在form表单中
            使用input,类型是button
            
    2后端响应格式如果是:html/text格式,ajax接收到数据后需要自己转成对象
        后端响应格式是:json,ajax接收到数据后会自动转成对象
        总结:后端返回数据,统一都用JsonResponse、
        
    3如果使用了ajax,后端就不要返回rediret,render,HttpResponse
        直接返回JsonResponse

    基于Ajax进行登录验证

    用户在表单输入用户名与密码,通过Ajax提交给服务器,服务器验证后返回响应信息,客户端通过响应信息确定是否登录成功,成功,则跳转到首页,否则,在页面上显示相应的错误信息

    # 创建用户表,提前录入用户信息
    class User(models.Model):
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=32)
    models.py
    urlpatterns = [
        url(r'^login/$', views.login),
    ]
    urls.py
    def login(request):
        if request.method == 'GET':
            return render(request, 'login.html')
        elif request.is_ajax():
            response = {'status': 100, 'msg': None}
            username = request.POST.get('username')
            password = request.POST.get('password')
            user_obj = models.User.objects.filter(username=username, password=password).first()
            if user_obj:
                # 用户名和密码都对了
                # return redirect('')  出错
                response['msg'] = '登录成功'
            else:
                response['status'] = 101
                response['msg'] = '用户名或密码错误'
    
            return JsonResponse(response)
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    </head>
    <body>
    <div class="col-md-6 col-md-offset-3">
        <div class="panel panel-primary">
            <div class="panel-heading">
                <h3 class="panel-title">网页</h3>
            </div>
            <div class="panel-body">
                <h1 class="text-center">登录</h1>
                <form action="" method="post">
                    <p>用户名:<input type="text" id="id_username" class="form-control"></p>
                    <p>密码:<input type="password" id="id_password" class="form-control"></p>
                    <input id="id_btn" type="button" value="提交" class="btn btn-primary btn-block"><span class="error"
                                                                                                        style="color: red"></span>
            </div>
        </div>
    </div>
    </body>
    <script>
        $('#id_btn').click(function () {
            $.ajax({
                url: '/login/',
                method: 'post',
                data: {username: $('#id_username').val(), password: $('#id_password').val()},
                success: function (data) {
                    // data 现在是对象类型
                    {#console.log(data)#}
                    if (data.status == 100) {
                        //登录成功,重定向到百度,前端重定向
                        location.href = '/'
    
                    } else {
                          //登录失败
                        $('.error').html(data.msg)
                    }
                },
                error: function (data) {
                    console.log(data)
                }
            })
    
        })
    </script>
    </html>
    login.html

    2 上传文件(ajax和form两种方式)

    1 http --post--请求,有编码格式,主流有三种
        urlencoded :默认的----》从request.POST取提交的数据
        form-data :上传文件的----》从request.POST取提交的数据,request.FILES中取文件
        json      :ajax发送json格式数据-----》request.POST取不出数据了
        
    2 使用ajax和form表单,默认都是urlencoded格式
    3 如果上传文件:form表单指定格式,ajax要使用Formdata对象 4 如果编码方式是urlencoded格式,放到body体中数据格式如下 username=lqz&password=123 5 如果是formdata编码格式,body体中是:两部分,数据和文件 6 如果是json格式,body体中的格式是:就是json格式字符串 -注意:注意:注意:如果这种格式,request.POST取不到值了

    form表单上传文件

    urlpatterns = [ 
        url(r'^file_upload/', views.file_upload),    
    ]
    urls.py
    def file_upload(request):
        if request.method == 'GET':
            return render(request,'file_upload.html')
        else:
            name = request.POST.get('name')
            myfile = request.FILES.get('myfile') # 拿到文件
            print(type(myfile)) # 查看类型
            with open(myfile.name, 'wb') as f:
                for line in myfile:
                    f.write(line)
    
            return HttpResponse('上传成功')
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    
    <h1>form表单上传文件</h1>
    <form action="" method="post" enctype="multipart/form-data">
        <p>用户名:<input type="text" name="name"></p>
        <p>文件:<input type="file" name="myfile"></p>
        <input type="submit" value="提交">
    
    </form>
    </body>
    </html>
    file_upload.html

    ajax 上传文件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    
    <h1>ajax上传文件</h1>
    <p>用户名:<input type="text" id="id_name"></p>
    <p>文件:<input type="file" id="id_myfile"></p>
    <button id="id_btn">提交</button>
    </body>
    
    <script>
    
        $('#id_btn').click(function () {
            //如果要上传文件,需要借助于一个js的FormData对象
    
            var formdata = new FormData() //实例化得到一个FormData对象
            formdata.append('name', $('#id_name').val()) //追加了一个name对应填入的值
            //能追加文件
            var file = $('#id_myfile')[0].files[0]
            formdata.append('myfile', file)
            $.ajax({
                url: 'file_upload',
                method: 'post',
                //上传文件,一定要注意如下两行
                processData: false,  //不预处理数据,
                contentType: false,  //不指定编码格式,使用formdata对象的默认编码就是formdata格式
                data: formdata,
                success: function (data) {
                    console.log(data)
    
                }
            })
    
        })
    </script>
    </html>
    file_upload.html

    3 ajax上传json格式

    urlpatterns = [
     
        url(r'^ajax_json/', views.ajax_json),
     
    ]
    urls.py
    def ajax_json(request):
        import json
        if request.method == 'GET':
            return render(request,'ajax_json.html')
    
        else:
            # json格式,从POST中取不出来
            name = request.POST.get('name')
            print(type(request.POST)) # 实际上不是一个真正的字典格式
            # from  django.http.request import QueryDict
            print(name)
            # 在body体中,b格式
            request.data = json.loads(request.body)
    
            name = request.data.get('name')  # 拿到用户名
            password = request.data.get('password') # 拿到密码 
            print(name)
            print(password)
            return HttpResponse('ok')
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    </head>
    <body>
    
    <h1>ajax提交json格式</h1>
    
    <p>用户名: <input type="text" id="id_name"></p>
    <p>密码: <input type="password" id="id_password"></p>
    <button id="id_button">提交</button>
    </body>
    
    <script>
    
        $('#id_button').click(function () {
    
            $.ajax({
                url: '/ajax_json/',
                method: 'post',
                contentType: 'application/json',  //json格式需指定编码格式
                  // 放json格式字符串
                data: JSON.stringify({name:$('#id_name').val(),password:$('#id_password').val()}),
                success: function (data) {
                    console.log(data)
    
                }
            })
    
        })
    </script>
    </html>
    ajax_json.html

    使用ajax上传json格式数据,写一个装饰器,实现不论前端以什么格式传递数据,我从视图函数中都从request.data中取值(POST的数据)

    urlpatterns = [
        url(r'^test_json/', views.test_json),
    
    ]
    urls.py
    from django.shortcuts import render, redirect, HttpResponse
    from django.http import JsonResponse
    
    from app01 import models
    import json
    
    
    def json_paser(func):
        def inner(request, *args, **kwargs):
            if request.method == 'POST':
                try:
                    """
                  只有post请求才有这种情况,get请求就不用管了
                  直接去loads.body,如果body里面是json格式,毫无疑问就有值了
                  能够loads到就只有一种情况就是通过json格式传过来的,其它两种
                  情况就会抛异常
                    """
                    request.data = json.loads(request.body)
                except Exception as e:
                    request.data = request.POST
    
            res = func(request, *args, **kwargs)
            return res
    
        return inner
    
    
    @json_paser
    def test_json(request):
        if request.method == 'GET':
            return render(request, 'test_json.html')
        else:
            print(request.data)
            return HttpResponse('ok')
            # return render(request,'book_page.html') # 返回的是一个纯的html页面
            # return redirect('http://www.baidu.com') # 直接报错
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    </head>
    <body>
    
    <button id="id_button">点我</button>
    </body>
    <script>
        $('#id_button').click(function () {
            $.ajax({
                url: '/test_json/',
                method: 'post',
                contentType: 'application/json',
                data: JSON.stringify({name: 'lqz', age: 18}),
                {#data:{name:'lqz',age:19},#} //urlencoded格式提交
                success: function (data) {
                    console.log(data)
    
    
                }
            })
        })
    
    </script>
    </html>
    test_json

    补充知识

    json.loads(b'dfdasfda')
    问题:json可以直接loads bytes格式吗?
      -3.5之前不可以
      -3.6以后可以

    Django内置的serializers(把对象序列化成json字符串)(了解)

    把对象转成json格式字符串,返回给前端,django内置的不好用,字段不能控制

    目前阶段,要做序列化,for循环拼列表套字典

    from django.core import serializers
    urlpatterns = [
        url(r'^test/', views.test),
    ]
    urls.py
    def test(request):
        user_list = models.User.objects.all()
        ret = serializers.serialize("json", user_list)
    
        return HttpResponse(ret)
    views.py
    class User(models.Model):
        name=models.CharField(max_length=32)
        password=models.CharField(max_length=32)
    models.py

     

    从来就没有正确的选择,我们只不过是要努力奋斗,使当初的选择变得正确。
  • 相关阅读:
    Bootstrap模态框modal的高度和宽度设置
    入门学习Linux常用必会命令实例详解
    Linux 系统中用户切换(su user与 su
    hdu 3549 Flow Problem(最大流模板题)
    第三章 学后心得及总结 【物联网1132-11】
    Find Minimum in Rotated Sorted Array 旋转数组中找最小值 @LeetCode
    面试题4
    Fp关联规则算法计算置信度及MapReduce实现思路
    POJ 1679 The Unique MST 推断最小生成树是否唯一
    论程序猿的社会地位
  • 原文地址:https://www.cnblogs.com/gfeng/p/14586574.html
Copyright © 2011-2022 走看看