如何利用AJAX获取Django后端数据详解
作者:运维派 发布时间:2022-06-13 13:51:43
使用Django服务网页时,只要用户执行导致页面更改的操作,即使该更改仅影响页面的一小部分,它都会将完整的HTML模板传递给浏览器。但是如果我们只想更新页面的一部分,则不必完全重新渲染页面-这时候就要用到AJAX了。
使用AJAX获取Django后端数据插图
AJAX提供了一种将GET或POST请求发送到Django视图并接收任何返回的数据而无需刷新页面的方法。现代JavaScript包含fetch API,该API为我们提供了一种纯JavaScript方式来发送AJAX请求。
让我们看一下如何通过获取发出GET和POST请求,以在视图和模板之间传递JSON数据。
GET请求
通过获取发出GET请求
通过向其提供视图的URL和适当的headers参数来进行获取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
})
Python
URL
提取将URL作为其第一个参数。根据Django项目的URLconf和视图的配置方式,URL可能包含关键字参数或查询字符串,我们希望在视图中使用该参数来选择请求的数据。
Headers
设置AJAX请求头参数。我们希望数据以JSON形式从视图返回,因此我们将Accept参数设置为application/json。在视图中,我们可能要确保该请求是AJAX请求。通过将设置为“XMLHttpRequest”的“X-Requested-With”标头包括在内,该视图将能够检查请求是否为AJAX。
get不会直接返回数据。它将返回一个response,该response将返回所请求的响应。为了从响应中获取数据,我们必须通过多次使用.then处理程序来使用链式response。第一个.then接收已解析的响应并将其转换为JSON。第二个.then允许我们访问第一个.then返回的数据,并允许我们使用它,然后可以处理这个数据,比如进行更新页面操作。
在视图中处理GET请求
我们需要一个视图来处理来 * tch调用的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,该序列将数据字典序列化并将其发送回我们的页面,在此页面中将通过链接进行处理。现在,我们可以使用JavaScript使用GET请求中的数据来更新页面的一部分。
POST请求
通过提取发出POST请求
带GET的POST请求比GET请求需要更多的参数。
fetch(URL, {
method: 'POST',
credentials: 'same-origin',
headers:{
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest', //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及更高版本
在即将发布的Django3.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请求的便捷方法,但并非所有浏览器(即所有版本的InternetExplorer)都支持提取。如果需要支持IE,请查看jQuery或XMLHttpRequest来发出AJAX请求。
AJAX请求应仅限于Django项目的一小部分。如果发现自己在多个模板中使用它们来获取大量数据,请考虑使用Django Rest Framework创建API。
总结
通过在Django项目中使用AJAX请求,我们可以更改页面的某些部分而无需重新加载整个页面。提取API使添加此功能相当轻松,同时需要最少的JavaScript。正确而谨慎地使用它,可以使我们的页面感觉更快,并为用户提供更多的交互体验。
来源:http://www.yunweipai.com/39829.html
猜你喜欢
- 多线程:在同一个时间做多件事守护线程:如果在程序中将子线程设置为守护线程,则该子线程会在主线程结束时自动退出,设置方式为thread.set
- 听说最近流行JQ风格的语法,不流行EXT风格了一.//ajax类fw=window.fw||{};fw.ajax = { &nbs
- 在使用SQL Server 的过程,中由于经常需要从多个不同地点将数据集中起来或向多个地点复制数据,所以数据的导出,导入是极为常见的操作.我
- 一个非常实用的小方法试想一下,Django中如果我们想对保存进数据库的数据做校验,有哪些实现的方法?我们可以在view中去处理,每当view
- html文件中引入js文件,显示乱码!js文件为utf-8 编码(无bom) ,此时只要将js文件转成utf-8 BOM编码就可
- 本文程序针对Python选课系统进行开发,供大家参考,具体内容如下角色:学校、学员、课程、讲师要求:1. 创建北京、上海 2 所学校2. 创
- 如下所示:import numpy as npimport matplotlib.pyplot as pltx = np.linspace(
- 从publish 表中取出第 n 条到第 m 条的记录的sql语句写法:SELECT TOP m-n+1 *&
- 起由:前一阵子想要刷一刷国二Python的题库,千方百计找到题库之后,打开一个个word文档,发现一题一题阅读很麻烦,而且答案就在题目的下面
- 查询效率分析:子查询为确保消除重复值,必须为外部查询的每个结果都处理嵌套查询。在这种情况下可以考虑用联接查询来取代。如果要用子查询,那就用E
- 目录Mock概念Mock类简单的例子体验下 Mock 的功能特点一个相对正式的 Mock 例子一个完整的测试例子断言方法Mock概念mock
- 以下针对Ubuntu系统,Windows系统没有测试过。Ubuntu中默认就安装有Python 2.x和Python 3.x,默认情况下py
- 之前看到好友在发各种"群发"来检验对方是不是把自己删除了,好吧,其实那个没啥用处.所以决定自己动手做一个百度了一下,检测
- 如下所示:mystring.strip().replace(' ', '').replace('\n
- 注:我指一个网站被第三方网站以iframe的形式调用时,被调用网站的禁止策略 和 调用网站的突破禁止策略,跟XSS麽关系,但跟clickja
- 前言:又到每日分享Python小技巧的时光了,今天给大家分享的是Python接口常用封装函数。相信对于封装,大家都不陌生吧,今天就用四个小案
- 这是来自于Steven D编写的WEB前端开发设计要点的内容。虽然许多设计师已非常熟练的使用了Web标准,让人遗憾的是有很多细节的排版处理仍
- 作者:Lachlan Hunt概要网络是不断的进化的. 新的和有创意的网站每天都在出现, 从各方面都在冲击着HTML的边界. HTML 4来
- 1. 安装vim:# apt-get install -y vim-gnome2. 安装ctags,ctags用于支持tagli
- 本文实例为大家分享了python实现网络五子棋的具体代码,供大家参考,具体内容如下服务器端:import osimport socketim