1. 程式人生 > 程式設計 >使用AJAX和Django獲取資料的方法例項

使用AJAX和Django獲取資料的方法例項

前言

使用Django服務網頁時,只要使用者執行導致頁面更改的操作,即使該更改僅影響頁面的一小部分,它都會將完整的HTML模板傳遞給瀏覽器。 但是如果我們只想更新頁面的一部分,則不必完全重新渲染頁面-我們可以使用AJAX代替。

AJAX提供了一種將GET或POST請求傳送到Django檢視並接收任何返回的資料而無需重新整理頁面的方法。 現代JavaScript包含fetch API,該API為我們提供了一種純JavaScript方式來發送AJAX請求。

讓我們看一下如何通過獲取發出GET和POST請求,以在檢視和模板之間傳遞JSON資料。

GET請求

通過獲取發出GET請求

通過向其提供檢視的URL和適當的標頭來進行帶有獲取的GET請求。 發出請求後,檢視返回請求的資料,然後需要將響應轉換為JSON,然後才能將其用於其他操作。

fetch(URL,{
  headers:{
   'Accept': 'application/json','X-Requested-With': 'XMLHttpRequest',//Necessary to work with request.is_ajax()
  },})
 .then(response => {
  return response.json() //Convert response to JSON
 })
 .then(data => {
  //Perform actions with the response data from the view
 })

URL

提取將URL作為其第一個引數。根據Django專案的URLconf和檢視的配置方式,URL可能包含關鍵字引數或查詢字串,我們希望在檢視中使用該引數來選擇請求的資料。

Headers

通過提取進行的AJAX請求將包含多個標頭。我們希望資料以JSON形式從檢視返回,因此我們將'Accept'標頭設定為'application / json'。在檢視中,我們可能要確保該請求是AJAX請求。通過將設定為“ XMLHttpRequest”的“ X-Requested-With”標頭包括在內,該檢視將能夠檢查請求是否為AJAX。

提取不會直接返回資料。相反,它將返回一個承諾,該承諾將被兌現並解決所請求的響應。為了從響應中獲取資料,我們必須通過多次使用.then處理程式來使用鏈式承諾。第一個.then接收已解析的響應並將其轉換為JSON。第二個.then允許我們訪問第一個.then返回的資料,並允許我們使用它,但是我們想更新頁面。

在檢視中處理GET請求
我們需要一個檢視來處理來自fetch呼叫的AJAX請求。這可以通過多種方式完成,但是最簡單的方法之一就是使用基於函式的檢視,該檢視接受請求並返回帶有請求資料的JsonResponse。

# views.py
from django.http import JsonResponse

def ajax_get_view(request): # May include more arguments depending on URL parameters
 # Get data from the database - Ex. Model.object.get(...)
 data = {
   'my_data':data_to_display
 }
 return JsonResponse(data)

如果通過包含附加引數的URL訪問該檢視,則這些附加引數也將與請求一起包含在功能引數列表中。 將根據那些URL引數或查詢字串(如果使用的話)從資料庫中檢索資料。 我們要傳送回頁面的資料必須在提供給JsonResponse的字典中。 呼叫之前,請確保從django.http匯入JsonResponse。

該檢視將返回JsonResponse,該序列將資料字典序列化並將其傳送回我們的頁面,在此頁面中將通過連結的promise進行處理。 現在,我們可以使用JavaScript使用GET請求中的資料來更新頁面的一部分。

POST請求

通過提取發出POST請求

帶GET的POST請求比GET請求需要更多的引數。

fetch(URL,{
  method: 'POST',credentials: 'same-origin',headers:{
   'Accept': 'application/json',//Necessary to work with request.is_ajax()
   'X-CSRFToken': csrftoken,},body: JSON.stringify({'post_data':'Data to post'}) //JavaScript object of data to POST
 })
 .then(response => {
  return response.json() //Convert response to JSON
 })
 .then(data => {
 //Perform actions with the response data from the view
 })

Method

提取預設為發出GET請求。我們必須通過新增方法“ POST”來明確地告訴它發出POST請求。

Credentials

我們需要指定如何在請求中傳送憑據。憑證可能很棘手,特別是如果專案的前端和後端分別託管。如果AJAX請求是通過與後端其他位置相同的模板提供的,我們可以使用預設值“ same-origin”。這意味著,如果所請求的URL與提取呼叫來自同一站點,則將在請求中傳送使用者憑據。如果前端和後端不在某個位置,則需要使用不同的憑據設定,並且需要考慮跨域資源共享(CORS)。

Headers

“ Accept”和“ X-Requested-With”標頭與GET請求的標頭相同,但是現在必須包括一個附加的“ X-CSRFToken”標頭。

向Django發出POST請求時,我們需要包含csrf令牌以防止跨站點請求偽造攻擊。 Django文件提供了我們需要新增的確切JavaScript程式碼,以從csrftoken cookie中獲取令牌。

function getCookie(name) {
  let cookieValue = null;
  if (document.cookie && document.cookie !== '') {
   const cookies = document.cookie.split(';');
   for (let i = 0; i < cookies.length; i++) {
    const cookie = cookies[i].trim();
    // 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;
 }
 const csrftoken = getCookie('csrftoken');

現在我們有了csrftoken,我們將其新增到標頭中作為“ X-CSRFToken”:csrftoken。

BODY

POST請求的目標是將資料傳送到檢視並更新資料庫。 這意味著我們還需要在fetch呼叫中包含資料。 假設我們要傳送JSON資料,我們新增主體:JSON.stringify(data)其中data是我們要傳送的資料的JavaScript物件。 除了JSON資料(包括檔案和來自表單的資料)外,其他資料也可以在正文中傳送。 有關如何包含其他型別的資料的更多資訊,請參見MDN文件。

我們從POST請求中獲得的響應將像GET請求一樣使用鏈式承諾進行處理。

在檢視中處理POST請求

接受POST請求的檢視將從請求中獲取資料,對其執行一些操作,然後返回響應。

# views.py
from django.http import JsonResponse
import json

def ajax_post_view(request):
 data_from_post = json.load(request)['post_data'] #Get data from POST request
 #Do something with the data from the POST request
 #If sending data back to the view,create the data dictionary
 data = {
  'my_data':data_to_display,}
 return JsonResponse(data)

我們認為,我們需要從AJAX請求中提取資料才能使用它。資料以JSON格式傳送,因此我們需要使用json.load(request)將其載入到檢視中。這需要從Python標準庫中匯入json模組。結果是我們通過提取傳送的資料的字典。現在,我們可以通過其鍵訪問資料。

一旦獲得了請求中的資料,我們就可以執行使用者希望啟動AJAX請求的操作。這可能是建立模型的新例項或更新現有例項。

與GET請求一樣,可以使用JsonResponse和帶有資料的字典將資料傳送回頁面。這可以是新的或更新的模型物件,也可以是成功訊息。

確保請求是AJAX

在大多數情況下,都會發出AJAX請求,因為我們只希望更新頁面的一部分,並且需要獲取新資料來進行更新。在頁面上下文之外,JsonResponse返回的資料本身很少使用。但是,如果我們沒有正確設定檢視,則可以在AJAX請求之外訪問資料,並且不會像我們期望的那樣將其呈現給使用者。

為了防止這種情況的發生,我們可以使用request.is_ajax()方法在檢視中新增檢查以確保該請求是AJAX請求。

# views.py
from django.http import JsonResponse

def ajax_view(request):
 if request.is_ajax():
  data = {
    'my_data':data_to_display
  }
  return JsonResponse(data)

這使用“ X-Requested-With”標頭來確定請求是否由AJAX發起。 如果嘗試通過直接在瀏覽器中鍵入URL來訪問此檢視,則會收到錯誤訊息。 可以向檢視中新增其他邏輯(例如重定向),以防止使用者嘗試在沒有AJAX請求的情況下訪問檢視時看到錯誤。

Django 3.1及更高版本

在即將釋出的Django 3.1版本(2020年8月)中,request.is_ajax()將被棄用。 這意味著如果我們要檢查AJAX請求,則必須自己重新建立功能。 幸運的是,Django開發人員確切地告訴我們我們需要做什麼。 我們必須自己從request.is_ajax()方法重新建立邏輯,該邏輯只有1行程式碼:

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

現在,我們可以編輯檢視以包括此檢查:

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

一些重要注意事項

儘管獲取是發出AJAX請求的便捷方法,但並非所有瀏覽器(即所有版本的Internet Explorer)都支援提取。 如果需要支援IE,請檢視jQuery或XMLHttpRequest來發出AJAX請求。

AJAX請求應僅限於Django專案的一小部分。 如果發現自己在多個模板中使用它們來獲取大量資料,請考慮使用Django Rest Framework建立API。

概要

通過在Django專案中使用AJAX請求,我們可以更改頁面的某些部分而無需重新載入整個頁面。 提取API使新增此功能相當輕鬆,同時需要最少的JavaScript。 正確而謹慎地使用它,可以使我們的頁面感覺更快,併為使用者提供更多的互動體驗。

原文:https://www.brennantymrak.com/articles/fetching-data-with-ajax-and-django.html

總結

到此這篇關於使用AJAX和Django獲取資料的文章就介紹到這了,更多相關AJAX和Django獲取資料內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!