zoukankan      html  css  js  c++  java
  • 058.Python前端Django与Ajax


    一 Ajax简介

    AJAXAsynchronous Javascript And XML)翻译成中文就是异步JavascriptXML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。

    • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
    • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

    AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

    优点:

    1. AJAX使用Javascript技术向服务器发送异步请求
    2. AJAX无须刷新整个页面

    二 AJAX的异步请求

    设计路由

    复制代码
    from django.contrib import admin
    from django.urls import path
    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('add_book/',views.add_book),
        path('query_book/',views.query_book),
        #ajax相关
        path('ajax_sleep/',views.ajax_sleep),
        path('ajax_test/',views.ajax_test),
        #前端页面
        path('ajax_temp/',views.ajax_temp),
    ]
    复制代码

    views视图文件

    复制代码
    def ajax_sleep(request):
        import  time
        time.sleep(3)
        return HttpResponse("sleep 3 senond")
    
    def ajax_test(request):
        return HttpResponse("test...")
    
    def ajax_temp(request):
        return render(request,"ajax_temp.html")
    复制代码

    html文件

    root@darren-virtual-machine:~/PycharmProjects/orm_demo# vim templates/ajax_temp.html

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <button id="btn1">ajax_sleep</button>
    <button id="btn2">ajax_test</button>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    
    <script>
        $("#btn1").click(function () {
            $.ajax({
                url:"/ajax_sleep/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
        $("#btn2").click(function () {
            $.ajax({
                url:"/ajax_test/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
    </script>>
    </body>
    </html>
    复制代码

    访问http://127.0.0.1:8000/ajax_temp/,先点击ajax_sleep然后点击test,这时在sleep中间正在执sleep代码,但是在点击test,也会执行,先于sleep输出,说明是一个异步操作,同时点击test后,页面并不会刷新,是一个局部刷新的动作

    三 实现ajax的一个计算案例

    制作一个如下页面,当在前面输入两个数字,点击提交触发后,会把结果填在第三个框里

    设计路由

    复制代码
    from django.contrib import admin
    from django.urls import path
    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('add_book/',views.add_book),
        path('query_book/',views.query_book),
        #ajax相关
        path('ajax_sleep/',views.ajax_sleep),
        path('ajax_test/',views.ajax_test),
        #前端页面
        path('ajax_temp/',views.ajax_temp),
        #ajax求和
        path('ajax_sum/',views.ajax_sum),
    ]
    复制代码

    view视图

    复制代码
    def ajax_sum(request):
        if request.is_ajax():
            num1 = request.POST.get("num1")
            num2 = request.POST.get("num2")
            total = int(num1) + int(num2)
            return HttpResponse(total)
    复制代码

    html 

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <button id="btn1">ajax_sleep</button>
    <button id="btn2">ajax_test</button>
    
    <hr>
    <div>
        <input type="text" id="i1"> + <input type="text" id="i2"> =
        <input type="text" id="i3"><button id="btn3">计算</button>
    </div>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    
    <script>
        $("#btn1").click(function () {
            $.ajax({
                url:"/ajax_sleep/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
    
        $("#btn2").click(function () {
            $.ajax({
                url:"/ajax_test/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
        {# 计算案例 #}
        $('#btn3').click(function () {
            var num1 = $("#i1").val();
            var num2 = $("#i2").val();
            $.ajax({
                url: "/ajax_sum/",
                type: "POST",
                data:{
                    num1:num1,
                    num2:num2,
                },
                success:function (data) {
                    $("#i3").val(data);
                }
            })
        })
    </script>
    </body>
    </html>
    复制代码

    访问http://127.0.0.1:8000/ajax_temp/

     

    403报错

    是由于crfs影响,添加crfs

    修改html

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <button id="btn1">ajax_sleep</button>
    <button id="btn2">ajax_test</button>
    {% csrf_token %}
    <hr>
    <div>
        <input type="text" id="i1"> + <input type="text" id="i2"> =
        <input type="text" id="i3"><button id="btn3">计算</button>
    
    </div>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    <script>
        {# 计算案例 #}
        $('#btn3').click(function () {
            var num1 = $("#i1").val();
            var num2 = $("#i2").val();
            $.ajax({
                url: "/ajax_sum/",
                type: "POST",
                data:{
                    num1:num1,
                    num2:num2,
                    csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
                },
                success:function (data) {
                    $("#i3").val(data);
                }
            })
        })
    </script>
    </body>
    </html>
    复制代码

    再次访问,并输入计算值,点击计算

     ajax请求流程

    当输入非数字计算

    调试信息

      File "/root/PycharmProjects/orm_demo/app01/views.py", line 131, in ajax_sum
        total = int(num1) + int(num2)
    ValueError: invalid literal for int() with base 10: 'qq'
    [08/Apr/2020 03:48:19] "POST /ajax_sum/ HTTP/1.1" 500 14677

    view视图文件

    复制代码
    from django.shortcuts import render,HttpResponse
    from app01 import models
    from django.http import JsonResponse
    
    def ajax_sum(request):
        if request.is_ajax():
            num1 = request.POST.get("num1")
            num2 = request.POST.get("num2")
            ret = {"status":1,"msg":None}
            try:
                total = int(num1) + int(num2)
                ret["msg"] = total
            except Exception as e:
                ret['status'] = 0
                ret["msg"] = "请输入数字"
            #需要使用到数据结构,使用json方式传过去,先要导入jsonhttponse
            return JsonResponse(ret)
    复制代码

    html调整

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <button id="btn1">ajax_sleep</button>
    <button id="btn2">ajax_test</button>
    {% csrf_token %}
    <hr>
    <div>
        <input type="text" id="i1"> + <input type="text" id="i2"> =
        <input type="text" id="i3"><button id="btn3">计算</button><span id="s1"></span>  {#多加一个span标签#}
    
    </div>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    <script>
        {# 计算案例 #}
        $('#btn3').click(function () {
            var num1 = $("#i1").val();
            var num2 = $("#i2").val();
            $.ajax({
                url: "/ajax_sum/",
                type: "POST",
                data:{
                    num1:num1,
                    num2:num2,
                    csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
                },
            {#默认传输的值是1,就会把传过来的msg值输入,挡status值为0时,就会把自定义的提示显示,和view视图文件对应#} success:function (data) { if (data.status){ $("#i3").val(data.msg); }else{ $("#s1").text(data.msg); } } }) }) </script> </body> </html>
    复制代码

    输入非数字时,会有提示

    问题,当再次输入正确格式,提示不会小时,

    使用定时器解决,显示2秒后消失

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <button id="btn1">ajax_sleep</button>
    <button id="btn2">ajax_test</button>
    {% csrf_token %}
    <hr>
    <div>
        <input type="text" id="i1"> + <input type="text" id="i2"> =
        <input type="text" id="i3"><button id="btn3">计算</button><span id="s1"></span>
    
    </div>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    <script>
        {# 计算案例 #}
        $('#btn3').click(function () {
            var num1 = $("#i1").val();
            var num2 = $("#i2").val();
            $.ajax({
                url: "/ajax_sum/",
                type: "POST",
                data:{
                    num1:num1,
                    num2:num2,
                    csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
                },
                success:function (data) {
                    if (data.status){
                        $("#i3").val(data.msg);
                    }else{
                        $("#s1").text(data.msg);
                        setTimeout(function () {
                            $("#s1").text("");
                        },2000)
                    }
                }
            })
        })
    </script>
    </body>
    </html>
    复制代码

    访问后,输入错误值,两秒后消失

    四 基于Ajax上传json数据

    url设计

    复制代码
    from django.contrib import admin
    from django.urls import path
    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('add_book/',views.add_book),
        path('query_book/',views.query_book),
        #ajax相关
        path('ajax_sleep/',views.ajax_sleep),
        path('ajax_test/',views.ajax_test),
        #前端页面
        path('ajax_temp/',views.ajax_temp),
        #ajax求和
        path('ajax_sum/',views.ajax_sum),
        #ajax上传json数据
        path('ajax_json/',views.ajax_json),
    ]
    复制代码

    views视图文件

    视图响应时,必须是HttpResponse 或者 HttpResponse,不能是render或者redict

    复制代码
    def ajax_json(request):
        import json
        print(request.POST)
        print(request.body)
        data = json.loads(request.body.decode())
        print(data)
        return  HttpResponse("Ok")
    复制代码

    html文件

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <button id="btn1">ajax_sleep</button>
    <button id="btn2">ajax_test</button>
    <button id="btn4">上传json数据</button>
    {% csrf_token %}
    <hr>
    <div>
        <input type="text" id="i1"> + <input type="text" id="i2"> =
        <input type="text" id="i3"><button id="btn3">计算</button><span id="s1"></span>
    
    </div>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    <script>
        {# 异步案例 #}
        $("#btn1").click(function () {
            $.ajax({
                url:"/ajax_sleep/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
    
        $("#btn2").click(function () {
            $.ajax({
                url:"/ajax_test/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
        {# 计算案例 #}
        $('#btn3').click(function () {
            var num1 = $("#i1").val();
            var num2 = $("#i2").val();
            $.ajax({
                url: "/ajax_sum/",
                type: "POST",
                data:{
                    num1:num1,
                    num2:num2,
                    csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
                },
                success:function (data) {
                    if (data.status){
                        $("#i3").val(data.msg);
                    }else{
                        $("#s1").text(data.msg);
                        setTimeout(function () {
                            $("#s1").text("");
                        },2000)
                    }
                }
            })
        });
        $("#btn4").click(function () {
            $.ajax({
                url:"/ajax_json/",
                type: "POST",
                contentType:"json",
                headers: {"X-CSRFToken": $("[name='csrfmiddlewaretoken']").val()}, // 在请求头中添加csrf
                data: JSON.stringify({
                    a:100,
                    b:200,
                    user:"darren",
                }),
                success:function (data) {
                    console.log(data)
                }
            })
        })
    </script>
    </body>
    </html>
    复制代码

    访问点击提交json数据

    得到结果

    调试输出

    <QueryDict: {}>
    b'{"a":100,"b":200,"user":"darren"}'
    {'a': 100, 'b': 200, 'user': 'darren'}

    在使用视图文件时,当使用HttpResponse返回时,前端代码需要使用json的数据,必须需要使用JSON.parse(data){}反序列化才能使用

    当使用JsonResponse(ret)返回时,可以直接使用,例如sum案例

    五 基于form表单上传文件

    下载一张图片到桌面备用,test111.png

    url文件

    复制代码
    from django.contrib import admin
    from django.urls import path
    from app01 import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('add_book/',views.add_book),
        path('query_book/',views.query_book),
        #ajax相关
        path('ajax_sleep/',views.ajax_sleep),
        path('ajax_test/',views.ajax_test),
        #前端页面
        path('ajax_temp/',views.ajax_temp),
        #ajax求和
        path('ajax_sum/',views.ajax_sum),
        #ajax上传json数据
        path('ajax_json/',views.ajax_json),
        #form表单上传
        path('upload/',views.upload),
    ]
    复制代码

    views

    复制代码
    import  os
    def upload(request):
        if request.method == "POST":
            print(request.POST)
            print(request.FILES)
            #print(request.body)  报错
            file_obj = request.FILES.get('file_name')
            name = file_obj.name
            with open(os.path.join("media", name), "wb") as f:
                for i in file_obj:
                    f.write(i)
            return HttpResponse('上传成功')
    复制代码

    html写一个form表单

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <button id="btn1">ajax_sleep</button>
    <button id="btn2">ajax_test</button>
    <button id="btn4">上传json数据</button>
    {% csrf_token %}
    <hr>
    <div>
        <input type="text" id="i1"> + <input type="text" id="i2"> =
        <input type="text" id="i3"><button id="btn3">计算</button><span id="s1"></span>
    
    </div>
    <hr>
    <h3>form表单上传文件</h3>
    <form action="/upload/" method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="text" name="user">
        <input type="file" name="file_name">
        <input type="submit">
    </form>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    <script>
        {# 异步案例 #}
        $("#btn1").click(function () {
            $.ajax({
                url:"/ajax_sleep/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
    
        $("#btn2").click(function () {
            $.ajax({
                url:"/ajax_test/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
        {# 计算案例 #}
        $('#btn3').click(function () {
            var num1 = $("#i1").val();
            var num2 = $("#i2").val();
            $.ajax({
                url: "/ajax_sum/",
                type: "POST",
                data:{
                    num1:num1,
                    num2:num2,
                    csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
                },
                success:function (data) {
                    if (data.status){
                        $("#i3").val(data.msg);
                    }else{
                        $("#s1").text(data.msg);
                        setTimeout(function () {
                            $("#s1").text("");
                        },2000)
                    }
                }
            })
        });
        $("#btn4").click(function () {
            $.ajax({
                url:"/ajax_json/",
                type: "POST",
                contentType:"json",
                headers: {"X-CSRFToken": $("[name='csrfmiddlewaretoken']").val()}, // 在请求头中添加csrf
                data: JSON.stringify({
                    a:100,
                    b:200,
                    user:"darren",
                }),
                success:function (data) {
                    console.log(data)
                }
            })
        })
    </script>
    </body>
    </html>
    复制代码

    root@darren-virtual-machine:~/PycharmProjects/orm_demo# mkdir media

    访问,选择文件

    点击submit,上传成功

    调试输出

    <QueryDict: {'csrfmiddlewaretoken': ['JA1GUiIv2LZCvSTxFjP8IOMaW7MNb3q3tjI5nOtFyXv6RETZxqq729rBOTFlFkE5'], 'user': ['']}>
    <MultiValueDict: {'file_name': [<InMemoryUploadedFile: test111.jpeg (image/jpeg)>]}>

    服务器查看

    root@darren-virtual-machine:~/PycharmProjects/orm_demo# ll media/

    六 基于Ajax请求上传文件

    修改html

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <button id="btn1">ajax_sleep</button>
    <button id="btn2">ajax_test</button>
    <button id="btn4">上传json数据</button>
    {% csrf_token %}
    <hr>
    <div>
        <input type="text" id="i1"> + <input type="text" id="i2"> =
        <input type="text" id="i3"><button id="btn3">计算</button><span id="s1"></span>
    
    </div>
    <hr>
    <h3>form表单上传文件</h3>
    {#  <form action="/upload/" method="POST" enctype="multipart/form-data"> #}
        {% csrf_token %}
        <input type="text" id="user" name="user">
        <input type="file" id="file1" name="file_name">
    <button id="btn5">ajax上传文件</button>
    {#    <input type="submit"> #}
    {# </form> #}
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    <script>
        {# 异步案例 #}
        $("#btn1").click(function () {
            $.ajax({
                url:"/ajax_sleep/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
    
        $("#btn2").click(function () {
            $.ajax({
                url:"/ajax_test/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
        {# 计算案例 #}
        $('#btn3').click(function () {
            var num1 = $("#i1").val();
            var num2 = $("#i2").val();
            $.ajax({
                url: "/ajax_sum/",
                type: "POST",
                data:{
                    num1:num1,
                    num2:num2,
                    csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
                },
                success:function (data) {
                    if (data.status){
                        $("#i3").val(data.msg);
                    }else{
                        $("#s1").text(data.msg);
                        setTimeout(function () {
                            $("#s1").text("");
                        },2000)
                    }
                }
            })
        });
        $("#btn4").click(function () {
            $.ajax({
                url:"/ajax_json/",
                type: "POST",
                contentType:"json",
                headers: {"X-CSRFToken": $("[name='csrfmiddlewaretoken']").val()}, // 在请求头中添加csrf
                data: JSON.stringify({
                    a:100,
                    b:200,
                    user:"darren",
                }),
                success:function (data) {
                    console.log(data)
                }
            })
        })
    </script>
    </body>
    </html>
    复制代码

    调试

    添加ajax

    复制代码
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <button id="btn1">ajax_sleep</button>
    <button id="btn2">ajax_test</button>
    <button id="btn4">上传json数据</button>
    {% csrf_token %}
    <hr>
    <div>
        <input type="text" id="i1"> + <input type="text" id="i2"> =
        <input type="text" id="i3"><button id="btn3">计算</button><span id="s1"></span>
    
    </div>
    <hr>
    <h3>form表单上传文件</h3>
    {#  <form action="/upload/" method="POST" enctype="multipart/form-data"> #}
        {% csrf_token %}
        <input type="text" id="user" name="user">
        <input type="file" id="file1" name="file_name">
    <button id="btn5">ajax上传文件</button>
    {#    <input type="submit"> #}
    {# </form> #}
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    <script>
        {# 异步案例 #}
        $("#btn1").click(function () {
            $.ajax({
                url:"/ajax_sleep/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
    
        $("#btn2").click(function () {
            $.ajax({
                url:"/ajax_test/",
                type:"GET",
                success:function (data) {
                    console.log(data);
                }
                }
            )
        })
        {# 计算案例 #}
        $('#btn3').click(function () {
            var num1 = $("#i1").val();
            var num2 = $("#i2").val();
            $.ajax({
                url: "/ajax_sum/",
                type: "POST",
                data:{
                    num1:num1,
                    num2:num2,
                    csrfmiddlewaretoken: $("[name=csrfmiddlewaretoken]").val(),
                },
                success:function (data) {
                    if (data.status){
                        $("#i3").val(data.msg);
                    }else{
                        $("#s1").text(data.msg);
                        setTimeout(function () {
                            $("#s1").text("");
                        },2000)
                    }
                }
            })
        });
        $("#btn4").click(function () {
            $.ajax({
                url:"/ajax_json/",
                type: "POST",
                contentType:"json",
                headers: {"X-CSRFToken": $("[name='csrfmiddlewaretoken']").val()}, // 在请求头中添加csrf
                data: JSON.stringify({
                    a:100,
                    b:200,
                    user:"darren",
                }),
                success:function (data) {
                    console.log(data)
                }
            })
        })
        {# ajax上传文件 #}
        $("#btn5").click(function () {
            var formdata = new FormData();
            formdata.append("csrfmiddlewaretoken", $("[name='csrfmiddlewaretoken']").val());
            formdata.append("file_name",$("#file1")[0].files[0]);
            $.ajax({
                url: "/upload/",
                type: "POST",
                processData: false,  // 告诉jQuery不要去处理发送的数据
                contentType: false,  // 告诉jQuery不要去设置Content-Type请求头
                data: formdata,
                success:function (data) {
                    console.log(data)
                }
            })
        })
    </script>
    </body>
    </html>
    复制代码

    修改图片名为test222

    点击ajax上传文件

    检查服务器文件

    root@darren-virtual-machine:~/PycharmProjects/orm_demo# ll media/

    七 请求头ContentType

    ContentType指的是请求体的编码类型,常见的类型共有3种:

    1.  application/x-www-form-urlencoded应该是最常见的 POST 提交数据的方式了。浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。
    2.  multipart/form-data是另一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 enctype 等于 multipart/form-data。
    3.  application/json:这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。 

     

    学习记录,小白一枚
  • 相关阅读:
    jython resources
    Installing a Library of Jython ScriptsPart of the WebSphere Application Server v7.x Administration Series Series
    jython好资料
    ulipad install on 64bit win7 has issue
    an oracle article in high level to descibe how to archtichre operator JAVA relevet project
    table的宽度,单元格内换行问题
    Linux常用命令大全
    dedecms系统后台登陆提示用户名密码不存在
    登录织梦后台提示用户名不存在的解决方法介绍
    Shell常用命令整理
  • 原文地址:https://www.cnblogs.com/wangsirde0428/p/14322905.html
Copyright © 2011-2022 走看看