目錄javascript
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在瀏覽器上執行。
展現一個前端頁面 ,頁面有三個輸入框,一個提交按鈕,前面兩個輸入框輸入內容,點擊按鈕,同過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'), ]
咱們知道form表單,默認的向後端提交數據的編碼格式是urlencoded
urlencoded:
()=()&()=()
這種就是符合urlencoded數據格式
()=()&()=()
的urlencoded數據格式會自動解析,將結果打包給request.POST 用戶只須要從request.POST便可獲取對應信息formdata:
ajax默認的提交數據的編碼格式也是urlencoded
總結: django後端針對不一樣的編碼格式數據 會有不一樣的處理機制以及不一樣的獲取該數據的方法
注意:在先後端進行數據交互的時候,必定要表名所發的是什麼數據,是什麼格式的,而且必定要遵照,代表是什麼格式數據,就必定要發與之對應的數據格式。
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的形式來接收前端發送的數據的
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')
注意:
利用formdata對象 可以簡單的快速傳輸數據 (普通鍵值 + 文件)
有幾個參數
data:formdata # 對象 contentType:false # 不用任何編碼 由於formdata對象自帶編碼 django可以識 processData:false # 告訴瀏覽器不要處理個人數據 直接發就行
將用戶表的數據 查詢出來 返回給前端
給前端的是一個大字典 字典裏面的數據的一個個的字段
# 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 }} age: {{ user_obj.age }} gender: {{ 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())
下面咱們要作的一個案例就是這個sweetalert的一個二次確認框
# 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.彈出的上述模態框中,可能字體會被圖標掩蓋一部分,可經過調整字體的上外邊距來解決
在註冊表單中,當用戶填寫了用戶名後,把光標移開後,會自動向服務器發送異步請求。服務器返回這個用戶名是否已經被註冊過。
# 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')