Django:(4)Django和Ajax
向服務器發送請求的途徑:
1. 瀏覽器地址欄,默認get請求
2. form表單:
get請求;
post請求
3. a標簽,默認get請求
4. Ajax:get請求;post請求
Ajax的特點(記住):
(1) 異步請求
(2)局部刷新
AJAX(Asynchronous Javascript And XML)翻譯成中文就是“異步Javascript和XML”。即使用Javascript語言與服務器進行異步交互,傳輸的數據為XML(傳輸的數據不只是XML,現在更多使用json數據)。
- 同步交互:客戶端發出一個請求後,需要等待服務器響應結束後,才能發出第二個請求;
- 異步交互:客戶端發出一個請求後,無需等待服務器響應結束,就可以發出第二個請求。
優點:
- AJAX使用Javascript技術向服務器發送異步請求
- AJAX無須刷新整個頁面
基於Jquery的Ajax實現
目錄結構:
urls.py
from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path(‘admin/‘, admin.site.urls), path(r"index/",views.index), path(r"test_ajax/",views.test_ajax) # ajax的路徑需要有流程線(如,路由分發的路徑,視圖函數,頁面等) ]
views.py
from django.shortcuts import render,HttpResponse # Create your views here. def index(request): return render(request,"index.html") def test_ajax(request): return HttpResponse("hello world")
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> <h2>this is Index</h2> <button class="ajax">Ajax</button> <p class="content"></p> </body> <script> $(".ajax").click(function () { $.ajax({ {# ajax請求的url;IP的端口沒寫就默認為當前的 #} url:"/test_ajax/", {# 請求方式;默認get #} type:"get", {#回調函數#} success:function (data) { $(".content").html(data) } }) }) {# 上述Ajax流程:點擊button按鈕,通過ajax向 特定的url發送請求;服務器返回字符串 "hello world"並傳給回調函數的形參 data;回調函數決定怎麽在頁面上展示data #} </script> </html>
Ajax傳遞數據:通過 data:{ } 的形式 發送數據
urls.py
from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path(‘admin/‘, admin.site.urls), path(r"index/",views.index), path(r"plus/",views.plus) ]
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> <input type="text" class="val1">+<input type="text" class="val2">=<input type="text" class="val3"> <button class="cal">計算</button> </body> <script> $(".cal").click(function () { $.ajax({ url:"/plus/", type:"post", {#ajax的input中不需要添加 name 屬性,只需要 class或id 能找到它就行;但form表單需要利用 name屬性去取值#} data:{ {# input框中的值是字符串格式 #} "val1":$(".val1").val(), "val2":$(".val2").val() }, success:function (data) { $(".val3").val(data) } }) }) </script> </html>
views.py
from django.shortcuts import render,HttpResponse def plus(request): print(request.POST) val1 = request.POST.get("val1") val2 = request.POST.get("val2") val3 = int(val1) + int(val2) return HttpResponse(val3)
註:settings.py MIDDLEWARE 中的 ‘django.middleware.csrf.CsrfViewMiddleware‘ 需要註釋掉
基於Ajax的登陸驗證(跨語言的Json)
目錄結構同上;settings.py 也註釋掉 csrf
urls.py
from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path(‘admin/‘, admin.site.urls), path(r"index/",views.index), path(r"login/",views.login) ]
views.py
from django.shortcuts import render,HttpResponse from app01.models import User def login(request): print(request.POST) user = request.POST.get("user") psw = request.POST.get("psw") user_obj = User.objects.filter(name=user,psw=psw).first() res = {"user":None,"msg":None} if user_obj: # 能在數據庫中匹配出來 res["user"] = user_obj.name else: res["msg"] = "用戶名密碼錯誤" # 字典格式的數據類型不能直接發送,需要先轉化為字符串格式 import json # 利用json.dumps()序列化 return HttpResponse(json.dumps(res))
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> {#form表單的action也沒必要寫,其實form標簽也沒必要;只是習慣上把form控件標簽放到form中#} <form> 用戶名 <input type="text" class="user"> 密碼 <input type="password" class="psw"> {# 用ajax發請求時 input的type用"button",不要用"submit",否則就變成了form表單發送請求 #} <input type="button" value="submit" class="login_btn"><span class="error"></span> </form> </body> <script> {# 登陸驗證 #} $(".login_btn").click(function () { {# 把ajax內置在某個事件中 #} $.ajax({ url:"/login/", type:"post", data:{ "user":$(".user").val(), "psw":$(".psw").val() }, success:function (data) { console.log(data) {# 此時data為json字符串格式 #} console.log(typeof data) {# 此時data這個字符串交給JS去處理了;就需要用JS的反序列化方法 #} {# 只要該語言支持json接口,它就能反解成自己支持的數據類型:python的字典會反解成JS的對象({}),python的列表會反解成JS的數組([])#} {# JSON.parse()是JS的反序列化方法 #} var new_data = JSON.parse(data) console.log(new_data) console.log(typeof new_data) if (new_data.user){ {# location.href= 表示前端跳轉 #} location.href="https://www.baidu.com" }else { $(".error").html(new_data.msg).css({"color":"red","margin-left":"10px"}) } } }) }) </script> </html>
文件上傳:
請求頭ContentType:
ContentType指的是請求體的編碼類型,常見的類型共有3種:
1. application/x-www-form-urlencoded:這應該是最常見的 POST 提交數據的方式了。瀏覽器的原生 <form> 表單,如果不設置 enctype 屬性,那麽最終就會以 application/x-www-form-urlencoded 方式提交數據。請求類似於下面這樣
POST http://www.example.com HTTP/1.1 Content-Type: application/x-www-form-urlencoded;charset=utf-8 user=yuan&age=22
2. multipart/form-datamultipart/form-data:這又是一個常見的 POST 數據提交的方式。我們使用表單上傳文件時,必須讓 <form> 表單的 enctype
等於 multipart/form-data
3. application/json:Json格式的字符串作為請求頭
基於form表單的文件上傳
urls.py
from django.contrib import admin from django.urls import path from app01 import views urlpatterns = [ path(r"file_put/",views.file_put) ]
views.py
from django.shortcuts import render,HttpResponse def file_put(request): if request.method == "POST": # 1. 基於form表單的文件上傳 print(request.POST) # request.POST 只有在 contentType = urlencoded 時候才有數據 # 註意:上傳成功的文件放在 request.FILEs 這個屬性裏面 print(request.FILES) # 下載所上傳的文件 file_obj = request.FILES.get("avatar") # 文件對象有一個屬性 .name 表示文件名 with open(file_obj.name,"wb") as f: for line in file_obj: f.write(line) return HttpResponse("ok") return render(request,"file_put.html")
file_put.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> <h3>基於form表單的文件上傳</h3> 註意:上傳文件的form表單中要寫上 enctype="multipart/form-data" <form action="" method="post" enctype="multipart/form-data"> 用戶名 <input type="text" name="user"> 上傳文件 input的type屬性值是 "file" 頭像 <input type="file" name="avatar"> <input type="submit"> </script> </html>
利用Ajax上傳普通數據
views.py
from django.shortcuts import render,HttpResponse def file_put(request): if request.method == "POST": return HttpResponse("ok") return render(request,"file_put.html")
file_put.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> <h3>基於Ajax的文件上傳</h3> {# 利用Ajax上傳普通數據 #} <form action="" method="post"> 用戶名 <input type="text" name="user"> <input type="button" class="btn" value="Ajax"> </form> </body> <script> {#利用Ajax上傳普通數據 #} $(".btn").click(function () { $.ajax({ {#url不寫默認為當前路徑#} url: "", type: "post", {#不指定enctype,默認用application/x-www-form-urlencoded #} data: { a: 1, b: 2 }, success: function (data) { console.log(data) } }) }) {#不論是form表單還是Ajax都有一個默認的請求頭 application/x-www-form-urlencoded #} </script> </html>
Ajax傳遞Json數據
views.py
from django.shortcuts import render,HttpResponse def file_put(request): if request.method == "POST": # 3. Ajax傳遞Json數據 print("request.body",request.body) # request.body:請求報文中的請求體(請求體的源數據); # request.body b‘{"a":1,"b":2}‘ # 此數據可通過python的json.dumps()方法獲取 print("request.POST",request.POST) # 此時 request.POST 中沒有數據 # request.POST <QueryDict: {}> return HttpResponse("ok") return render(request,"file_put.html")
file_put.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> {#Ajax傳遞Json數據#} <form action="" method="post"> 用戶名 <input type="text" name="user"> <input type="button" class="btn" value="Ajax"> </form> </body> <script> {#Ajax傳遞Json數據#} $(".btn").click(function () { $.ajax({ {#url不寫默認為當前路徑#} url:"", type:"post", {#告訴服務器編碼類型為json數據#} contentType:"application/json", {#然後需要用JS的方法把數據變成Json數據類型:JSON.stringify():序列化 #} {#然後請求體中的數據就是 {"a":"1","b":"2"} 類型的json字符串 #} data:JSON.stringify({ a:1, b:2 }), success:function (data) { console.log(data) } }) }) </script> </html>
基於Ajax的文件上傳
from django.shortcuts import render,HttpResponse def file_put(request): if request.method == "POST": # 4. 基於Ajax的文件上傳 print("request.body", request.body) print("request.POST", request.POST) print(request.FILES) # 下載所上傳的文件 file_obj = request.FILES.get("avatar") # file_obj = request.FILES.get("avatar") # 文件對象有一個屬性 .name 表示文件名 with open(file_obj.name,"wb") as f: for line in file_obj: f.write(line) return HttpResponse("ok") return render(request,"file_put.html")
file_put.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> {# 基於Ajax的文件上傳 #} <form action="" method="post"> 用戶名 <input type="text" class="user"> 上傳文件 input的type屬性值是 "file" 頭像 <input type="file" class="avatar"> <input type="button" class="btn" value="Ajax"> </form> </body> <script> {# 基於Ajax的文件上傳 #} $(".btn").click(function () { {#涉及到文件上傳,一定要用 FormData 創建一個新的對象(formdata編碼);固定格式 #} var formdata = new FormData(); {#然後給創建的 formdata對象添加鍵值:append(key,value)方法 #} formdata.append("user",$(".user").val()); formdata.append("avatar",$(".avatar")[0].files[0]); {#$(".avatar")[0]是對應的 input 標簽,DOM元素;取DOM元素中包含的文件對象: .files[0],固定語法 #} $.ajax({ {#url不寫默認為當前路徑#} url:"", type:"post", {#傳formdata的時候一定要加上 contentType:false,processData:false, 這兩句代碼 #} {# contentType:false 表示不做編碼處理 #} contentType:false, {#processData:false表示不對數據做預處理#} processData:false, {#把formdata賦值給data#} data:formdata, success:function (data) { console.log(data) } }) }) </script> </html>
Django:(4)Django和Ajax