自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用AJAX獲取Django后端數(shù)據(jù)

開發(fā) 前端
讓我們看一下如何通過獲取發(fā)出GET和POST請(qǐng)求,以在視圖和模板之間傳遞JSON數(shù)據(jù)。

[[395869]]

 使用Django服務(wù)網(wǎng)頁時(shí),只要用戶執(zhí)行導(dǎo)致頁面更改的操作,即使該更改僅影響頁面的一小部分,它都會(huì)將完整的HTML模板傳遞給瀏覽器。但是如果我們只想更新頁面的一部分,則不必完全重新渲染頁面-這時(shí)候就要用到AJAX了。

AJAX提供了一種將GET或POST請(qǐng)求發(fā)送到Django視圖并接收任何返回的數(shù)據(jù)而無需刷新頁面的方法?,F(xiàn)代JavaScript包含fetch API,該API為我們提供了一種純JavaScript方式來發(fā)送AJAX請(qǐng)求。

讓我們看一下如何通過獲取發(fā)出GET和POST請(qǐng)求,以在視圖和模板之間傳遞JSON數(shù)據(jù)。

GET請(qǐng)求

  •  通過獲取發(fā)出GET請(qǐng)求

通過向其提供視圖的URL和適當(dāng)?shù)膆eaders參數(shù)來進(jìn)行獲取GET請(qǐng)求。發(fā)出請(qǐng)求后,視圖返回請(qǐng)求的數(shù)據(jù),然后需要將響應(yīng)轉(zhuǎn)換為JSON,然后才能將其用于其他操作。 

  1. fetch(URL, {  
  2.       headers:{  
  3.           'Accept': 'application/json',  
  4.           'X-Requested-With': 'XMLHttpRequest', //Necessary to work with request.is_ajax()  
  5.       },  
  6.   })  
  7.   .then(response => {  
  8.       return response.json() //Convert response to JSON  
  9.   })  
  10.   .then(data => {  
  11.       //Perform actions with the response data from the view  
  12.   }) 

URL

提取將URL作為其第一個(gè)參數(shù)。根據(jù)Django項(xiàng)目的URLconf和視圖的配置方式,URL可能包含關(guān)鍵字參數(shù)或查詢字符串,我們希望在視圖中使用該參數(shù)來選擇請(qǐng)求的數(shù)據(jù)。

Headers

設(shè)置AJAX請(qǐng)求頭參數(shù)。我們希望數(shù)據(jù)以JSON形式從視圖返回,因此我們將Accept參數(shù)設(shè)置為application/json。在視圖中,我們可能要確保該請(qǐng)求是AJAX請(qǐng)求。通過將設(shè)置為“XMLHttpRequest”的“X-Requested-With”標(biāo)頭包括在內(nèi),該視圖將能夠檢查請(qǐng)求是否為AJAX。

get不會(huì)直接返回?cái)?shù)據(jù)。它將返回一個(gè)response,該response將返回所請(qǐng)求的響應(yīng)。為了從響應(yīng)中獲取數(shù)據(jù),我們必須通過多次使用.then處理程序來使用鏈?zhǔn)絩esponse。第一個(gè).then接收已解析的響應(yīng)并將其轉(zhuǎn)換為JSON。第二個(gè).then允許我們?cè)L問第一個(gè).then返回的數(shù)據(jù),并允許我們使用它,然后可以處理這個(gè)數(shù)據(jù),比如進(jìn)行更新頁面操作。

在視圖中處理GET請(qǐng)求

我們需要一個(gè)視圖來處理來自fetch調(diào)用的AJAX請(qǐng)求。這可以通過多種方式完成,但是最簡(jiǎn)單的方法之一就是使用基于函數(shù)的視圖,該視圖接受請(qǐng)求并返回帶有請(qǐng)求數(shù)據(jù)的JsonResponse。 

  1. # views.py  
  2. from django.http import JsonResponse  
  3. def ajax_get_view(request): # May include more arguments depending on URL parameters  
  4.     # Get data from the database - Ex. Model.object.get(...)  
  5.     data = {  
  6.             'my_data':data_to_display  
  7.     }  
  8.     return JsonResponse(data) 

如果通過包含附加參數(shù)的URL訪問該視圖,則這些附加參數(shù)也將與請(qǐng)求一起包含在功能參數(shù)列表中。將根據(jù)那些URL參數(shù)或查詢字符串(如果使用的話)從數(shù)據(jù)庫中檢索數(shù)據(jù)。我們要發(fā)送回頁面的數(shù)據(jù)必須在使用JsonResponse。調(diào)用之前,請(qǐng)確保從django.http導(dǎo)入JsonResponse。

該視圖將返回JsonResponse,該序列將數(shù)據(jù)字典序列化并將其發(fā)送回我們的頁面,在此頁面中將通過鏈接進(jìn)行處理?,F(xiàn)在,我們可以使用JavaScript使用GET請(qǐng)求中的數(shù)據(jù)來更新頁面的一部分。

POST請(qǐng)求

  •  通過提取發(fā)出POST請(qǐng)求

帶GET的POST請(qǐng)求比GET請(qǐng)求需要更多的參數(shù)。 

  1. fetch(URL, {  
  2.       method: 'POST',  
  3.       credentials: 'same-origin',  
  4.       headers:{  
  5.           'Accept': 'application/json',  
  6.           'X-Requested-With': 'XMLHttpRequest', //Necessary to work with request.is_ajax()  
  7.           'X-CSRFToken': csrftoken,  
  8.   },  
  9.       body: JSON.stringify({'post_data':'Data to post'}) //JavaScript object of data to POST  
  10.   })  
  11.   .then(response => {  
  12.         return response.json() //Convert response to JSON  
  13.   }) 
  14.   .then(data => {  
  15.   //Perform actions with the response data from the view  
  16.   }) 

Method

默認(rèn)為發(fā)出GET請(qǐng)求。我們必須通過添加方法“ POST”來明確地告訴它發(fā)出POST請(qǐng)求。

Credentials

我們需要指定如何在請(qǐng)求中發(fā)送憑據(jù)。憑證可能很棘手,特別是如果項(xiàng)目的前端和后端分別托管。如果AJAX請(qǐng)求是通過與后端其他位置相同的模板提供的,我們可以使用默認(rèn)值“ same-origin”。這意味著,如果所請(qǐng)求的URL與提取調(diào)用來自同一站點(diǎn),則將在請(qǐng)求中發(fā)送用戶憑據(jù)。如果前端和后端不在某個(gè)位置,則需要使用不同的憑據(jù)設(shè)置,并且需要考慮跨域資源共享(CORS)。

Headers

“ Accept”和“ X-Requested-With”標(biāo)頭與GET請(qǐng)求的標(biāo)頭相同,但是現(xiàn)在必須包括一個(gè)附加的“ X-CSRFToken”標(biāo)頭。

向Django發(fā)出POST請(qǐng)求時(shí),我們需要包含csrf令牌以防止跨站點(diǎn)請(qǐng)求偽造攻擊。Django文檔提供了我們需要添加的確切JavaScript代碼,以從csrftoken cookie中獲取令牌。 

  1. function getCookie(name) {  
  2.       let cookieValue = null 
  3.       if (document.cookie && document.cookie !== '') {  
  4.           const cookies = document.cookie.split(';');  
  5.           for (let i = 0; i < cookies.length; i++) {  
  6.               const cookie = cookies[i].trim();  
  7.               // Does this cookie string begin with the name we want?  
  8.               if (cookie.substring(0, name.length + 1) === (name + '=')) {  
  9.                   cookieValue = decodeURIComponent(cookie.substring(name.length + 1));  
  10.                   break;  
  11.               }  
  12.           }  
  13.       }  
  14.       return cookieValue;  
  15.   } 
  16.    const csrftoken = getCookie('csrftoken'); 

現(xiàn)在我們有了csrftoken,我們將其添加到標(biāo)頭中作為“X-CSRFToken”:csrftoken。

BODY

POST請(qǐng)求的目標(biāo)是將數(shù)據(jù)發(fā)送到視圖并更新數(shù)據(jù)庫。這意味著我們還需要在fetch調(diào)用中包含數(shù)據(jù)。假設(shè)我們要發(fā)送JSON數(shù)據(jù),我們添加主體:JSON.stringify(data)其中data是我們要發(fā)送的數(shù)據(jù)的JavaScript對(duì)象。除了JSON數(shù)據(jù)(包括文件和來自表單的數(shù)據(jù))外,其他數(shù)據(jù)也可以在正文中發(fā)送。有關(guān)如何包含其他類型的數(shù)據(jù)的更多信息,請(qǐng)參見MDN文檔。

我們從POST請(qǐng)求中獲得的響應(yīng)將像GET請(qǐng)求一樣使用鏈?zhǔn)匠兄Z進(jìn)行處理。

在視圖中處理POST請(qǐng)求

接受POST請(qǐng)求的視圖將從請(qǐng)求中獲取數(shù)據(jù),對(duì)其執(zhí)行一些操作,然后返回響應(yīng)。 

  1. # views.py  
  2. from django.http import JsonResponse  
  3. import json  
  4. def ajax_post_view(request):  
  5.     data_from_post = json.load(request)['post_data'] #Get data from POST request  
  6.     #Do something with the data from the POST request  
  7.     #If sending data back to the view, create the data dictionary  
  8.     data = {  
  9.         'my_data':data_to_display,  
  10.     }  
  11.     return JsonResponse(data) 

我們需要從AJAX請(qǐng)求中提取數(shù)據(jù)才能使用它。數(shù)據(jù)以JSON格式發(fā)送,因此我們需要使用json.load(request)將其加載到視圖中。這需要從Python標(biāo)準(zhǔn)庫中導(dǎo)入json模塊。結(jié)果是我們通過提取發(fā)送的數(shù)據(jù)的字典?,F(xiàn)在,我們可以通過其鍵訪問數(shù)據(jù)。

一旦獲得了請(qǐng)求中的數(shù)據(jù),我們就可以執(zhí)行用戶希望啟動(dòng)AJAX請(qǐng)求的操作。這可能是創(chuàng)建模型的新實(shí)例或更新現(xiàn)有實(shí)例。

與GET請(qǐng)求一樣,可以使用JsonResponse和帶有數(shù)據(jù)的字典將數(shù)據(jù)發(fā)送回頁面。這可以是新的或更新的模型對(duì)象,也可以是成功消息。

確保請(qǐng)求是AJAX

在大多數(shù)情況下,都會(huì)發(fā)出AJAX請(qǐng)求,因?yàn)槲覀冎幌M马撁娴囊徊糠郑⑶倚枰@取新數(shù)據(jù)來進(jìn)行更新。在頁面上下文之外,JsonResponse返回的數(shù)據(jù)本身很少使用。但是,如果我們沒有正確設(shè)置視圖,則可以在AJAX請(qǐng)求之外訪問數(shù)據(jù),并且不會(huì)像我們期望的那樣將其呈現(xiàn)給用戶。

為了防止這種情況的發(fā)生,我們可以使用request.is_ajax()方法在視圖中添加檢查以確保該請(qǐng)求是AJAX請(qǐng)求。 

  1. # views.py  
  2. from django.http import JsonResponse  
  3. def ajax_view(request):  
  4.     if request.is_ajax():  
  5.         data = {  
  6.                 'my_data':data_to_display  
  7.         }  
  8.         return JsonResponse(data) 

這使用“ X-Requested-With”標(biāo)頭來確定請(qǐng)求是否由AJAX發(fā)起。如果嘗試通過直接在瀏覽器中鍵入U(xiǎn)RL來訪問此視圖,則會(huì)收到錯(cuò)誤消息??梢韵蛞晥D中添加其他邏輯(例如重定向),以防止用戶嘗試在沒有AJAX請(qǐng)求的情況下訪問視圖時(shí)看到錯(cuò)誤。

Django 3.1及更高版本

在即將發(fā)布的Django3.1版本(2020年8月)中,request.is_ajax()將被棄用。這意味著如果我們要檢查AJAX請(qǐng)求,則必須自己重新創(chuàng)建功能。幸運(yùn)的是,Django開發(fā)人員確切地告訴我們我們需要做什么。我們必須自己從request.is_ajax()方法重新創(chuàng)建邏輯,該邏輯只有1行代碼:

  1. request.headers.get('x-requested-with') == 'XMLHttpRequest' 

現(xiàn)在,我們可以編輯視圖以包括此檢查: 

  1. def ajax_view(request):  
  2.   if request.headers.get('x-requested-with') == 'XMLHttpRequest':  
  3.     # Get requested data and create data dictionary  
  4.     return JsonResponse(data)) 

一些重要注意事項(xiàng)

盡管獲取是發(fā)出AJAX請(qǐng)求的便捷方法,但并非所有瀏覽器(即所有版本的InternetExplorer)都支持提取。如果需要支持IE,請(qǐng)查看jQuery或XMLHttpRequest來發(fā)出AJAX請(qǐng)求。

AJAX請(qǐng)求應(yīng)僅限于Django項(xiàng)目的一小部分。如果發(fā)現(xiàn)自己在多個(gè)模板中使用它們來獲取大量數(shù)據(jù),請(qǐng)考慮使用Django Rest Framework創(chuàng)建API。

總結(jié)

通過在Django項(xiàng)目中使用AJAX請(qǐng)求,我們可以更改頁面的某些部分而無需重新加載整個(gè)頁面。提取API使添加此功能相當(dāng)輕松,同時(shí)需要最少的JavaScript。正確而謹(jǐn)慎地使用它,可以使我們的頁面感覺更快,并為用戶提供更多的交互體驗(yàn)。 

 

責(zé)任編輯:龐桂玉 來源: 馬哥Linux運(yùn)維
相關(guān)推薦

2021-09-03 07:39:44

數(shù)據(jù)交互AxiosAjax

2017-10-11 18:17:06

大數(shù)據(jù)數(shù)據(jù)可視化前后端

2023-10-31 16:46:45

2021-09-18 10:24:08

DjangoRedis緩存后端

2009-05-20 14:49:16

ibmdwAjaxWeb開發(fā)

2011-01-24 13:20:49

2022-09-01 07:18:21

分離項(xiàng)目Vue

2012-04-19 10:04:20

ibmdw

2011-10-28 14:01:30

jQuery

2013-01-15 11:22:29

AjaxASP.NET

2024-10-31 13:56:30

FastAPIGradioDjango

2021-06-09 09:36:18

DjangoElasticSearLinux

2011-06-16 14:08:20

JSONAjax

2021-11-16 10:45:35

WebSocketWebShellLinux

2015-07-16 15:20:58

DockerDjango

2021-12-08 09:59:02

Django 4.0哈希器Redis緩存

2015-12-25 16:37:02

RxJava數(shù)據(jù)源數(shù)據(jù)

2024-08-12 13:19:32

2024-06-07 09:30:22

vue2Vuex存儲(chǔ)

2012-09-28 10:18:53

IBMdw
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)