前言
使用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', '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"htmlcode"># 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
总结
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]