Django框架 之 Ajax
Django框架 之 Ajax
瀏覽目錄
-
AJAX準備知識
-
AJAX與XML的比較
-
AJAX簡介
-
jQuery實現的ajax
-
AJAX參數
-
AJAX請求如何設置csrf_token
-
序列化
?
一、AJAX準備知識
1、什么是json
- JSON 指的是 JavaScript 對象表示法(JavaScript?Object?Notation)
- JSON 是輕量級的文本數據交換格式
- JSON 獨立于語言?*
- JSON 具有自我描述性,更易理解
*?JSON 使用 JavaScript 語法來描述數據對象,但是 JSON 仍然獨立于語言和平臺。JSON 解析器和 JSON 庫支持許多不同的編程語言。
需要知道的:json的格式來源于js的格式
1、js支持單引號,也支持雙引號,也可以沒有引號
| 1 2 3 4 5 6 | //在js中吧{}這樣的類型叫做對象,js中沒有字典一說 data?=?{ ????'name':'haiyan', ????"name":"haiyan", ?????name:"haiyan"??????? }?????//js對象默認會把自己的鍵當成字符串處理,所以可以加引號也可以不加 |
2、json的格式:
| 1 2 | 1、json只認雙引號的 2、json一定是一個字符串 |
3、下面我們看看哪些是合格的字符串,哪些不是?
合格的json對象
| 1 2 3 4 | ["one",?"two",?"three"] {?"one":?1,?"two":?2,?"three":?3?} {"names": ["張三",?"李四"] } [ {?"name":?"張三"}, {"name":?"李四"} ] |
不合格的json對象
| 1 2 3 4 5 6 7 | { name:?"張三",?'age':?32?}??//?屬性名必須使用雙引號 [32,?64,?128,?0xFFF]?//?不能使用十六進制值 {?"name":?"張三",?"age": undefined }??//?不能使用undefined {?"name":?"張三", ??"birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'), ??"getName":? function() {return?this.name;}??//?不能使用函數和日期對象 } |
2、python中的序列化(dumps)與反序列化(loads)
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import?json i?=?10 s?=?"dsfdsf" l?=?[11,22,33] dic?=?{"name":"haiyna","age":22} b?=?True # #把基本數據類型轉換成字符串的形式 print(json.dumps(i),type(json.dumps(i)))???#10 <class 'str'> print(json.dumps(s),type(json.dumps(s)))???#"dsfdsf" <class 'str'> print(json.dumps(l),type(json.dumps(l)))???#[11, 22, 33] <class 'str'> print(json.dumps(dic),type(json.dumps(dic)))??#{"name": "haiyna", "age": 22} <class 'str'> print(json.dumps(b),type(json.dumps(b)))??#true <class 'str'> # ===============json序列化============= d?=?{"a":1,"b":"fdgfd"} data?=?json.dumps(d) print(data,type(data)) f?=?open("a.txt","w") f.write(data)???#注意這會寫進去的字符串時雙引號的格式 f.close() # ===============json反序列化============= <br>f = open("a.txt","r") <br>datat = f.read() <br>print(datat,type(datat)) #{"a": 1, "b": "fdgfd"} <class 'str'><br>data = json.loads(datat) <br>print(data,type(data)) #{'a': 1, 'b': 'fdgfd'} <class 'dict'> |
3、JS中的序列化(stringify)與反序列化(parse)
JSON.stringify():用于將一個JavaScript對象轉換為JSON字符串
| 1 | JSON.stringify({"name":"yaya"}) |
JSON.parse():用于將一個JSON字符串轉換為JavaScript對象
| 1 2 3 | JSON.parse('{"name":"yaya"}'); JSON.parse('{name:"yaya"}') ;???//?錯誤 JSON.parse('[18,undefined]') ;???//?錯誤 |
示例:
| 1 2 3 4 5 6 7 8 9 10 | <script> //===========js中的json反序列化=========== s?=?'{"name":1}';??? var data?=?JSON.parse(s); console.log(data); console.log(typeof data);???//object //===========js中的json的序列化======= s2={'name':'yuan'}; console.log(JSON.stringify(s2),typeof JSON.stringify(s2))??//string </script> |
二、AJAX與XML的比較
JSON 格式于2001年由 Douglas Crockford 提出,目的就是取代繁瑣笨重的 XML 格式。
JSON 格式有兩個顯著的優點:書寫簡單,一目了然;符合 JavaScript 原生語法,可以由解釋引擎直接處理,不用另外添加解析代碼。所以,JSON迅速被接受,已經成為各大網站交換數據的標準格式,并被寫入ECMAScript 5,成為標準的一部分。
XML和JSON都使用結構化方法來標記數據,下面來做一個簡單的比較。
用XML表示中國部分省市數據如下:
<?xml version="1.0" encoding="utf-8"?> <country><name>中國</name><province><name>黑龍江</name><cities><city>哈爾濱</city><city>大慶</city></cities></province><province><name>廣東</name><cities><city>廣州</city><city>深圳</city><city>珠海</city></cities></province><province><name>臺灣</name><cities><city>臺北</city><city>高雄</city></cities></province><province><name>新疆</name><cities><city>烏魯木齊</city></cities></province> </country>用JSON表示如下:
{"name": "中國","province": [{"name": "黑龍江","cities": {"city": ["哈爾濱", "大慶"]}}, {"name": "廣東","cities": {"city": ["廣州", "深圳", "珠海"]}}, {"name": "臺灣","cities": {"city": ["臺北", "高雄"]}}, {"name": "新疆","cities": {"city": ["烏魯木齊"]}}] }可以看出,JSON 簡單的語法格式和清晰的層次結構明顯要比 XML 容易閱讀,并且在數據交換方面,由于 JSON 所使用的字符要比 XML 少得多,可以大大得節約傳輸數據所占用得帶寬。
注意:
JSON格式取代了xml給網絡傳輸帶來了很大的便利,但是卻沒有了xml的一目了然,尤其是json數據很長的時候,我們會陷入繁瑣復雜的數據節點查找中。 但是國人的一款在線工具 BeJson 、SoJson在線工具讓眾多程序員、新接觸JSON格式的程序員更快的了解JSON的結構,更快的精確定位JSON格式錯誤。三、AJAX簡介
1、簡單介紹
我們以前知道的前端向后端發送數據的方式有:
GET:地址欄、a標簽、Form表單
POST:Form表單
現在我們在學習一種:那就是ajax
ajax:也是前端向后端發送數據的一種方式
AJAX(Asynchronous Javascript And XML)翻譯成中文就是“異步Javascript和XML”。即使用Javascript語言與服務器進行異步交互,傳輸的數據為XML(當然,傳輸的數據不只是XML)。
- 同步交互:客戶端發出一個請求后,需要等待服務器響應結束后,才能發出第二個請求;
- 異步交互:客戶端發出一個請求后,無需等待服務器響應結束,就可以發出第二個請求。
Ajax的特點:
異步交互: 當請求發出后,瀏覽器還可以進行其他操作,無需等待服務器的響應!
局部刷新:? ? 整個過程中頁面沒有刷新,只是刷新頁面中的局部位置而已!
示例:
頁面輸入兩個整數,通過AJAX傳輸到后端計算出結果并返回。
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>AJAX局部刷新實例</title> </head> <body><input type="text" id="i1">+ <input type="text" id="i2">= <input type="text" id="i3"> <input type="button" value="AJAX提交" id="b1"><script src="/static/jquery-3.2.1.min.js"></script> <script>$("#b1").on("click", function () {$.ajax({url:"/ajax_add/",type:"GET",data:{"i1":$("#i1").val(),"i2":$("#i2").val()},success:function (data) {$("#i3").val(data);}})}) </script> </body> </html> def ajax_demo1(request):return render(request, "ajax_demo1.html")def ajax_add(request):i1 = int(request.GET.get("i1"))i2 = int(request.GET.get("i2"))ret = i1 + i2return HttpResponse(ret, safe=False) urlpatterns = [...url(r'^ajax_add/', views.ajax_add),url(r'^ajax_demo1/', views.ajax_demo1),... ]2、AJAX常見應用場景
搜索引擎根據用戶輸入的關鍵字,自動提示檢索關鍵字。
還有一個很重要的應用場景就是注冊時候的用戶名的查重。
其實這里就使用了AJAX技術!當文件框發生了輸入變化時,使用AJAX技術向服務器發送一個請求,然后服務器會把查詢到的結果響應給瀏覽器,最后再把后端返回的結果展示出來。
- 整個過程中頁面沒有刷新,只是刷新頁面中的局部位置而已!
- 當請求發出后,瀏覽器還可以進行其他操作,無需等待服務器的響應!
?
當輸入用戶名后,把光標移動到其他表單項上時,瀏覽器會使用AJAX技術向服務器發出請求,服務器會查詢名為lemontree7777777的用戶是否存在,最終服務器返回true表示名為lemontree7777777的用戶已經存在了,瀏覽器在得到結果后顯示“用戶名已被注冊!”。
- 整個過程中頁面沒有刷新,只是局部刷新了;
- 在請求發出后,瀏覽器不用等待服務器響應結果就可以進行其他操作;
3、AJAX的優點
- AJAX使用JavaScript技術向服務器發送異步請求;
- AJAX請求無須刷新整個頁面;
- 因為服務器響應內容不再是整個頁面,而是頁面中的部分內容,所以AJAX性能高;?
四、jQuery實現的ajax
最基本的jQuery發送AJAX請求示例:
html頁面
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <!DOCTYPE html> <html lang="zh-CN"> <head> ??<meta charset="UTF-8"> ??<meta http-equiv="x-ua-compatible"?content="IE=edge"> ??<meta name="viewport"?content="width=device-width, initial-scale=1"> ??<title>ajax test</title> ??<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> </head> <body> <button?id="ajaxTest">AJAX 測試</button> <script> ??$("#ajaxTest").click(function () { ????$.ajax({ ??????url:?"/ajax_test/", ??????type:?"POST", ??????data: {username:?"yaya", password:?123456}, ??????success: function (data) { ????????alert(data) ??????} ????}) ??}) </script> </body> </html> |
views.py
| 1 2 3 4 5 | def?ajax_test(request): ????user_name?=?request.POST.get("username") ????password?=?request.POST.get("password") ????print(user_name, password) ????return?HttpResponse("OK") |
五、AJAX參數
請求參數
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | ######################------------data---------################ ???????data: 當前ajax請求要攜帶的數據,是一個json的object對象,ajax方法就會默認地把它編碼成某種格式 ?????????????(urlencoded:?a=1&b=2)發送給服務端;此外,ajax默認以get方式發送請求。 ?????????????function testData() { ???????????????$.ajax("/test",{?????//此時的data是一個json形式的對象 ??????????????????data:{ ????????????????????a:1, ????????????????????b:2 ??????????????????} ???????????????});???????????????????//?a=1&b=2 ######################------------processData---------################ processData:聲明當前的data數據是否進行轉碼或預處理,默認為true,即預處理;if為false, ?????????????那么對data:{a:1,b:2}會調用json對象的toString()方法,即{a:1,b:2}.toString() ?????????????,最后得到一個[object,Object]形式的結果。 ????????????? ######################------------contentType---------################ contentType:默認值:?"application/x-www-form-urlencoded"。發送信息至服務器時內容編碼類型。 ?????????????用來指明當前請求的數據編碼格式;urlencoded:?a=1&b=2;如果想以其他方式提交數據, ?????????????比如contentType:"application/json",即向服務器發送一個json字符串: ???????????????$.ajax("/ajax_get",{ ?????????????? ??????????????????data:JSON.stringify({ ???????????????????????a:22, ???????????????????????b:33 ???????????????????}), ???????????????????contentType:"application/json", ???????????????????type:"POST", ?????????????? ???????????????});??????????????????????????//{a:?22, b:?33} ?????????????注意:contentType:"application/json"一旦設定,data必須是json字符串,不能是json對象 ######################------------traditional---------################ traditional:一般是我們的data數據有數組時會用到 :data:{a:22,b:33,c:["x","y"]}, ??????????????traditional為false會對數據進行深層次迭代;? |
相應參數
| 1 2 3 4 5 6 7 8 9 10 11 12 | /* dataType:? 預期服務器返回的數據類型,服務器端返回的數據會根據這個值解析后,傳遞給回調函數。 ????????????默認不需要顯性指定這個屬性,ajax會根據服務器返回的content?Type來進行轉換; ????????????比如我們的服務器響應的content?Type為json格式,這時ajax方法就會對響應的內容 ????????????進行一個json格式的轉換,if轉換成功,我們在success的回調函數里就會得到一個json格式 ????????????的對象;轉換失敗就會觸發error這個回調函數。如果我們明確地指定目標類型,就可以使用 ????????????data?Type。 ????????????dataType的可用值:html|xml|json|text|script ????????????見下dataType實例 */ |
示例:
1 from django.shortcuts import render,HttpResponse2 from django.views.decorators.csrf import csrf_exempt3 # Create your views here.4 5 import json6 7 def login(request):8 9 return render(request,'Ajax.html') 10 11 12 def ajax_get(request): 13 14 l=['alex','little alex'] 15 dic={"name":"alex","pwd":123} 16 17 #return HttpResponse(l) #元素直接轉成字符串alexlittle alex 18 #return HttpResponse(dic) #字典的鍵直接轉成字符串namepwd 19 return HttpResponse(json.dumps(l)) 20 return HttpResponse(json.dumps(dic))# 傳到前端的是json字符串,要想使用,需要JSON.parse(data) 21 22 //--------------------------------------------------- 23 function testData() { 24 25 $.ajax('ajax_get', { 26 success: function (data) { 27 console.log(data); 28 console.log(typeof(data)); 29 //console.log(data.name); 30 //JSON.parse(data); 31 //console.log(data.name); 32 }, 33 //dataType:"json", 34 } 35 )} 36 37 注解:Response Headers的content Type為text/html,所以返回的是String;但如果我們想要一個json對象 38 設定dataType:"json"即可,相當于告訴ajax方法把服務器返回的數據轉成json對象發送到前端.結果為object 39 當然, 40 return HttpResponse(json.dumps(a),content_type="application/json") 41 42 這樣就不需要設定dataType:"json"了。 43 content_type="application/json"和content_type="json"是一樣的!六、AJAX請求如何設置csrf_token
方式一
| 1 2 3 4 5 6 7 8 9 10 11 12 | $.ajax({ ??url:?"/cookie_ajax/", ??type:?"POST", ??data: { ????"username":?"yaya", ????"password":?123456, ????"csrfmiddlewaretoken": $("[name = 'csrfmiddlewaretoken']").val()??//?使用JQuery取出csrfmiddlewaretoken的值,拼接到data中 ??}, ??success: function (data) { ????console.log(data); ??} }) |
方式二
通過獲取返回的cookie中的字符串 放置在請求頭中發送。
注意:需要引入一個jquery.cookie.js插件。
| 1 2 3 4 5 6 7 8 9 | $.ajax({ ??url:?"/cookie_ajax/", ??type:?"POST", ??headers: {"X-CSRFToken": $.cookie('csrftoken')},??//?從Cookie取csrf_token,并設置ajax請求頭 ??data: {"username":?"yaya",?"password":?123456}, ??success: function (data) { ????console.log(data); ??} }) |
或者用自己寫一個getCookie方法:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function getCookie(name) { ????var cookieValue?=?null; ????if?(document.cookie && document.cookie !==?'') { ????????var cookies?=?document.cookie.split(';'); ????????for?(var i?=?0; i < cookies.length; i++) { ????????????var cookie?=?jQuery.trim(cookies[i]); ????????????//?Does this cookie string begin with the name we want? ????????????if?(cookie.substring(0, name.length?+?1)?===?(name?+?'=')) { ????????????????cookieValue?=?decodeURIComponent(cookie.substring(name.length?+?1)); ????????????????break; ????????????} ????????} ????} ????return?cookieValue; } var csrftoken?=?getCookie('csrftoken'); |
每一次都這么寫太麻煩了,可以使用$.ajaxSetup()方法為ajax請求統一設置。
| 1 2 3 4 5 6 7 8 9 10 11 12 | function csrfSafeMethod(method) { ??//?these HTTP methods do?not?require CSRF protection ??return?(/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ ??beforeSend: function (xhr, settings) { ????if?(!csrfSafeMethod(settings.type) && !this.crossDomain) { ??????xhr.setRequestHeader("X-CSRFToken", csrftoken); ????} ??} }); |
更多細節詳見:Djagno官方文檔中關于CSRF的內容
七、序列化
Django內置的serializers
| 1 2 3 4 5 | def?books_json(request): ????book_list?=?models.Book.objects.all()[0:10] ????from?django.core?import?serializers ????ret?=?serializers.serialize("json", book_list) ????return?HttpResponse(ret) |
我們的數據中經常有日期時間,也就是datetime對象,而json.dumps是無法處理這樣在類型的,那就需要通過自定義處理器來做擴展,如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class?JsonCustomEncoder(json.JSONEncoder): ????""" ????自定義一個支持序列化時間格式的類 ????""" ????def?default(self, o): ????????if?isinstance(o, datetime): ????????????return?o.strftime("%Y-%m-%d %H:%M:%S") ????????elif?isinstance(o, date): ????????????return?o.strftime("%Y-%m-%d") ????????else: ????????????return?json.JSONEncoder.default(self, o) def?books_json(request): ????book_list?=?models.Book.objects.all().values_list("title",?"publish_date") ????ret?=?json.dumps(list(book_list),?cls=JsonCustomEncoder) ????return?HttpResponse(ret) |
?
?示例:文本框移除光標后顯示提示信息
class Userinfo(models.Model):name = models.CharField(max_length=32) from app01 import viewsurlpatterns = [url(r'^admin/', admin.site.urls),url(r"register",views.register),url(r"check_username",views.check_username), ] # 注冊頁面函數 def register(request):if request.method == "POST":passreturn render(request, "register.html")# 文本框對比函數 def check_username(request):# 取到用戶輸入的用戶名username = request.POST.get("username")# 跟數據庫中的用戶名做對比ret = models.Userinfo.objects.filter(name=username)# 如果存在if ret:return HttpResponse("該用戶已被注冊!")else:return HttpResponse("可以注冊!") <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><title>注冊</title><meta name="viewport" content="width=device-width, initial-scale=1"><style>.error{color: red;}</style></head> <body> <p>用戶名:<input type="text" id="username" name="username"><span class="error"></span> </p> <script src="/static/jquery-3.2.1.min.js"></script> <script src="/static/init_ajax.js"></script> {#直到輸入正確#} {#<script>#} {#$("#username").on("input",function () {#} {# var username = $(this).val();#} {# var $spanEle = $(this).next();#} {# $.ajax({#} {# url: "/check_username/",#} {# type: "POST",#} {# data: {"username": username},#} {# success: function (arg) {#} {# $spanEle.text(arg)#} {# }#} {# });#} {#})#} {#</script>#}<script> $("#username").on("blur",function () { //移除光標var username=$(this).val(); //取到輸入文本框中的值var $spanEle=$(this).next(); //找到span標簽$.ajax({url:"/check_username/", //往哪兒傳type:"POST", //請求方式data:{"username":username}, //請求提交的數據success:function (arg) { //請求成功執行的函數$spanEle.text(arg) //所有跟arg有關的數據都要寫在回調函數里}}) }) </script> </body> </html>?
轉載于:https://www.cnblogs.com/hanbowen/p/9566978.html
總結
以上是生活随笔為你收集整理的Django框架 之 Ajax的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 这五个超强PPT技巧,从小白到大神的距离
- 下一篇: 三极管和MOS场效应管的区别