15 Django Ajax

1、Ajax 介紹

Ajax是一種異步提交,就是在當前頁面時,不刷新當前頁面的前提下,將數據提交到另外一個頁面css

Ajax能夠局部刷新頁面,在一個頁面下,不總體刷新頁面,而是能夠將當前頁面的某一個部分刷新html

此處回憶一下同步異步/阻塞非阻塞前端

同步異步:描述的任務的提交方式java

同步:提交任務以後 原地等待任務的返回結果 期間不幹日他的事情python

異步::提交任務以後 不原地等待 直接執行下一行代碼 任務結果的返回經過回調機制jquery

阻塞非阻塞:程序的運行狀態------瞭解程序運行的狀態圖ajax

Ajax(Asynchronous Javascript And XML):翻譯成中文就是「異步的 Javascript和XML」。即便用Javascript語言與服務器進行異步交互,傳輸的數據爲XML(固然,傳輸的數據不僅是XML)。數據庫

Ajax不是新的編程語言,而是一種使用現有標準的新方法django

Ajax是一門 JS 技術,基於原生 JS 開發,但用原生的 JS 寫代碼太過於繁瑣,咱們用 JavaSquery是實現

提示:JavaSquery是基於javascript方法封裝的。。。。

Ajax最大的優勢:不從新加載整個頁面的狀況下,能夠與服務器交換數據並更新部分網頁內容。(這一特色給用戶的感覺是在不知不覺中完成請求和響應過程)

AJAX 不須要任何瀏覽器插件,但須要用戶容許JavaScript在瀏覽器上執行。

2、Ajax 實例

展現一個前端頁面 ,頁面有三個輸入框,一個提交按鈕,前面兩個輸入框輸入內容,點擊按鈕,同過Ajax實現點擊按鈕向後端提交數據,實現將前兩個輸入框中的數據計算和返回給第三個輸入框中顯示

# add_num.html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <title>Title</title>
</head>
<body>
<input id="i1" type="text">+<input id="i2" type="text">=<input id="i3" type="text">
<button>Ajax提交</button>

<script>
    {#1.先找到button這個對象,綁定點擊事件#}
    $('button').click(function () {
        {#2. 觸發ajax事件#}
        $.ajax({
            {#1. url:用來控制提交數據的地址,不寫默認的是當前的地址#}
            url:'',
            {#2. type:用來控制向地址提交的請求,能夠小寫#}
            type:'post',
            {#3. 用來向後端提交的數據#}
            data:{num1:$('#i1').val(),num2:$('#i2').val()},
            {#4. 接收從後端返回的數據,也就是異步返回的結果#}
            success:function(data){
                {#將結果給第三個輸入框#}
                $('#i3').val(data)
            }

        })
    })
</script>
</body>
</html>
# views.py文件

def add_num(request):
    # 判斷是否爲Ajax請求
    if request.is_ajax():
        if request.method == 'POST':
            num1 = request.POST.get('num1')
            num2 = request.POST.get('num2')
            data = int(num1)+int(num2)
            print(data)
            return HttpResponse(data)
    return render(request,'add_num.html')
# url.py文件
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    # 經過Ajax向後端傳數據將結果計算返回
    url(r'^add/$',views.add_num,name='add_page'),
]

3、contentType 交互的數據格式

咱們知道form表單,默認的向後端提交數據的編碼格式是urlencoded

urlencoded:

()=()&()=()這種就是符合urlencoded數據格式

  • django後端針對()=()&()=()的urlencoded數據格式會自動解析,將結果打包給request.POST 用戶只須要從request.POST便可獲取對應信息

formdata:

  • django後端針對formdata格式類型數據 也會自動解析,可是不會方法request.POST中而是給你放到了request.FILES中

ajax默認的提交數據的編碼格式也是urlencoded

總結: django後端針對不一樣的編碼格式數據 會有不一樣的處理機制以及不一樣的獲取該數據的方法

4、Ajax傳json格式數據

注意:在先後端進行數據交互的時候,必定要表名所發的是什麼數據,是什麼格式的,而且必定要遵照,代表是什麼格式數據,就必定要發與之對應的數據格式。

django後端針對前端頁面發送過來的 json 數據不會自動解析,會直接原封不動的給你放到request.body中,須要你手動處理,獲取數據

# json.html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <title>Title</title>
</head>
<body>

<input id="i1" type="text">
<input id="i1" type="text">
<button>提交</button>

<script>
    $('button').click(function () {
        $.ajax({
            url:'',
            type:'post',
            data:JSON.stringify({'name':'cecilia','pwd':'123'}),
            contentType:'application/json',
            success:function (data) {
                alert(data)
            }
        })
    })
</script>
</body>
</html>
#views.py文件
import json
def up_json(request):
    if request.is_ajax():
        if request.method == 'POST':
            json_bytes = request.body
            json_str = json_bytes.decode('utf8')
            json_dic = json.loads(json_str)
            print(json_dic,type(json_dic))
    return render(request,'json.html')

注意:當前端向後端發送的數據不是json格式的時候,django是默認不給看request.body中的內容的,必定要牢記,當前端向後端發送json格式數據的時候,全部的數據信息都是保存在request.body中的

在上圖中能夠看到,咱們已經在前端頁面中代表了我發的是json格式的數據,因此他提交的數據已經不在是向get和post的請求的那種()=()&()=()的形式了,因此在post天然是獲取不到任何數據的了

如上圖,咱們點擊view score的時候,咱們能夠看到瀏覽器也默認用application/json的形式來接收前端發送的數據的

5、Ajax向後端傳文件

Ajax向後端傳文件,須要用到內置對象Formdata,該對象既能夠傳普通的鍵值,也能夠傳文件

# upload_file.html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <title>Title</title>
</head>
<body>
<input type="text" name="username" id="t1">
<input type="text" name="password" id="t2">
<input type="file" name="myfile" id="t3">上傳文件
<button>提交</button>
<Script>
    $('button').click(function () {
         // 1.先生成一個formdata對象
        var myFormData = new FormData();
        // 2.朝對象中添加普通的鍵值
        myFormData.append('username',$("#t1").val());
        myFormData.append('password',$("#t2").val());
        // 3.朝對象中添加文件數據
        // 1.先經過jquery查找到該標籤
        // 2.將jquery對象轉換成原生的js對象
        // 3.利用原生js對象的方法 直接獲取文件內容
        myFormData.append('myfile',$('#t3')[0].files[0]);
        $.ajax({
            url:'',
            type:'post',
            data:myFormData,  // 直接丟對象
            // ajax傳文件 必定要指定兩個關鍵性的參數
            contentType:false,  // 不用任何編碼 由於formdata對象自帶編碼 django可以識別該對象
            processData:false,  // 告訴瀏覽器不要處理個人數據 直接發就行
            success:function (data) {
                alert(data)
            }
        })
    })
</Script>
</body>
</html>
# views.py文件
def upload_file(request):
    # 判斷請求是否爲Ajax請求
    if request.is_ajax():
        if request.method == 'POST':
            print(request.POST) # 這裏只是收到了普通的鍵值對
            print(request.FILES) # 上傳的文件的對象在這裏
            return  HttpResponse('收到')

    return render(request,'upload_file.html')

注意:

  1. 利用formdata對象 可以簡單的快速傳輸數據 (普通鍵值 + 文件)

  2. 有幾個參數

    data:formdata # 對象
    contentType:false # 不用任何編碼 由於formdata對象自帶編碼 django可以識
    processData:false # 告訴瀏覽器不要處理個人數據 直接發就行

6、給前端返回一個字典

將用戶表的數據 查詢出來 返回給前端
給前端的是一個大字典 字典裏面的數據的一個個的字段

# dict.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <title>Title</title>
</head>
<body>
{{user_list}}

{#這是最原始的利用模板語法來接收的大字典#}
{#{% for user_obj in user_list %}#}
{#    <p>username:{{ user_obj.username }}&nbsp;age:&nbsp;{{ user_obj.age }}&nbsp;gender:&nbsp;{{ user_obj.gender }}</p>#}
{#{% endfor %}#}

</body>
</html>
# views.py文件
from app01 import models
from django.core import serializers
def back_dic(request):
    user_obj_list = models.UserInfo.objects.all()
    # 1.原始的方式向前端頁面傳送字典
    # user_list = []
    # for user_obj in user_obj_list:
    #     user_list.append({
    #         'username':user_obj.username,
    #         'age':user_obj.age,
    #         'gender':user_obj.get_gender_display()
    #     })

    # 2. 利用serializers這個模塊來幫咱們很簡單的將對象變爲字典
    '''
    serializers:模塊有兩個參數
                1.format:表明序列成什麼格式的數據
                2.queryset:要序列化的對象
    '''
    user_list = serializers.serialize('json',user_obj_list)
    return  render(request,'dict.html',locals())

7、Ajax + sweetalert

下面咱們要作的一個案例就是這個sweetalert的一個二次確認框

img

# sweet.html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
    <script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
    <link rel="stylesheet" href="{% static 'sweetalert/dist/sweetalert.css' %}">
    <script src="{% static 'sweetalert/dist/sweetalert.js' %}"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1 ">
    <title>Title</title>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
        <h2>數據展現</h2>
            <table class="table table-bordered table-hover table-striped">
                <thead>
                    <tr>
                        <td>序號</td>
                        <td>姓名</td>
                        <td>年齡</td>
                        <td>性別</td>
                        <td class="text-center">編輯</td>
                    </tr>
                </thead>
                <tbody>
                    {% for user_obj in user_obj_list %}
                        <tr>
                            <td>{{forloop.counter }}</td>
                            <td>{{user_obj.username }}</td>
                            <td>{{user_obj.age}}</td>
                            <td>{{user_obj.get_gender_display}}</td>
                            <td>
                                <a href="#" class="btn btn-success">編輯</a>
                                <a href="#" class="btn btn-warning cancel"  del_id="{{ user_obj.pk }}">刪除</a>
                            </td>
                        </tr>
                    {% endfor %}

                </tbody>
            </table>
        </div>
    </div>
</div>
<script>
    $('.cancel').click(function () {
        var $btn = $(this);
        swal({
          title: "你肯定要刪嗎?",
          text: "你要是刪了,你就準備好跑路吧!",
          type: "warning",
          showCancelButton: true, //這是肯定俺就
          confirmButtonClass: "btn-danger",
          confirmButtonText: "對,老子就要刪!", //肯定按鈕的文本
          cancelButtonText: "算了,算了!", //這是取消刪除的文本內容
          closeOnConfirm: false,
          showLoaderOnConfirm: true//實現肯定按鈕後的加載後刪除
        },
        function(){
            $.ajax({
                url:'',
                type:'post',
                data:{'delete_id':$btn.attr('delete_id')},
                success:function (data) {
                    if (data.code){
                        swal(data.msg, "你能夠回去收拾行李跑路了.", "success");
                        // 1.直接刷新頁面
                        {#window.location.reload()#}
                        // 2.經過DOM操做 實時刪除
                        $btn.parent().parent().remove()
                    }else{
                        swal("發生了未知錯誤!", "我也不知道哪裏錯了.", "info");
                    }
                }
            });
        });
    })
</script>
</body>
</html>
# views.py文件
import time
from django.http import JsonResponse
def sweetalert(request):
    # 若是是get請求,就把用戶對象返回給前端頁面
    user_obj_list = models.UserInfo.objects.all()
   
    # 若是是POST請求,就刪除須要刪除的用戶對象
    if request.method == 'POST':
        # 先定義一個字典,做爲返回給前端頁面的
        back_dic = {"code":True,'msg':''}
        delete_id = request.POST.get('delete_id')
        models.UserInfo.objects.filter(pk=delete_id).delete()
        back_dic['msg'] = '後端傳來的:真的被我刪了'
        time.sleep(3)# 這裏是實現一個加載一段時間後刪除
        return JsonResponse(back_dic)
    return render(request,'sweet.html',locals())

補充:

1.上述的樣式類部分渲染的樣式來自於bootstrap中,全部建議在使用上述樣式時,將bootstrap的js和css也導入了,這樣的狀況下,頁面效果就不會有任何問題

2.彈出的上述模態框中,可能字體會被圖標掩蓋一部分,可經過調整字體的上外邊距來解決

img

8、Ajax 實例

7.1 input框失去焦點事件

在註冊表單中,當用戶填寫了用戶名後,把光標移開後,會自動向服務器發送異步請求。服務器返回這個用戶名是否已經被註冊過。

# register.html文件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <title>Title</title>
    <style>
        .aa{
            margin-top: 20px;
        }
        .bb{
            display: none;
        }
    </style>
</head>
<body>
<div class="container-fluid">
    <div class="row">
        <div class="col-sm-2 col-sm-offset-5" style="background-color: #dca7a7;margin-top: 50px">
            <div>
                <input class="form-control aa" type="text" name='username' value="輸入用戶名" id="i1">
            </div>
            <p><span class="bb aa" style="color: red">用戶名已存在</span></p>
            <div>
                <input class="form-control aa" type="text" name='pwd' value="輸入密碼" id="i2">
            </div>
{#            <div>#}
{#                <input class="form-control aa"  type="text" name='repwd' value="確認密碼" id="i3">#}
{#            </div>#}
            <div class="text-center">
                <input class="aa" type="radio" name='gender' value="1" id="i4">男
                <input class="aa" type="radio" name='gender' value="2" id="i5" checked>女
            </div>

            <div class="text-center">
                <button class="btn aa">註冊</button>
            </div>

        </div>
    </div>
</div>
<script>
    // 用戶名輸入框的失去焦點事件
    $('#i1').blur(function () {
        $.ajax({
            url:'',
            type:'post',
            data:{'username':$(this).val()}, //this表明的是當前的jq對象
            success:function (data) {
                back_dic=JSON.parse(data);//反序列化從後端傳回來的數據
                if (back_dic['flag']){ 
                    // 若是條件存在,就將標籤的bb類屬性去掉
                    $('p>span').removeClass('bb');
                }
            }
        })
    })
</script>
</body>
</html>
# views.py文件

def register(request):
    if request.method == 'POST':
        # 先定義一個字典,用於給前端返回數據
        back_dic = {'flag': False}
        # 拿到前端的post請求攜帶的參數
        username = request.POST.get('username')
        # 從數據庫中取這個username名的對象
        user_obj = models.UserInfo.objects.filter(username=username).first()
        if user_obj:
            # 若是這個對象存在
            back_dic['flag'] = True
            import json
            # 將返回序列化號的json格式的數據返回給前端頁面
            return HttpResponse(json.dumps(back_dic))
    return render(request,'register.html')
相關文章
相關標籤/搜索