Django中使用Fetch API进行AJAX数据交互指南

Aria
Aria
发布时间:2026-10-14| 4人浏览过
原创

本文详解如何在Django项目中利用现代JavaScript的Fetch API实现AJAX数据交互。涵盖GET与POST请求的配置、JSON数据传递、CSRF令牌处理及Django视图端的JsonResponse使用。针对Django 3.1+版本,提供了替代request.is_ajax()的跨浏览器兼容方案,帮助开发者实现无刷新页面更新。

Django AJAX数据交互概述

前言

在使用Django构建Web服务时,常规操作下用户触发的页面变更会导致整个HTML模板重新渲染并发送给浏览器。然而,若仅需更新页面的局部内容,完全重新加载页面显得效率低下。此时,采用AJAX技术可实现局部刷新,避免全页重载。

AJAX允许前端向Django视图发送GET或POST请求,并在不刷新页面的情况下接收返回数据。现代JavaScript内置的Fetch API为此提供了原生支持,使得通过纯JavaScript发送AJAX请求变得简洁高效。

接下来,我们将通过具体示例展示如何利用Fetch API发起GET和POST请求,从而在Django视图与前端模板之间高效传递JSON格式的数据。

GET请求的实现与处理

GET请求

通过Fetch发出GET请求

发起带有Fetch的GET请求时,需指定视图URL及必要的请求头。请求发出后,视图返回数据,前端需将响应转换为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

Fetch函数以URL作为首个参数。根据Django项目的URLconf配置,URL可能包含关键字参数或查询字符串,前端需正确构造这些参数以便视图筛选所需数据。

Headers

Fetch发起的AJAX请求包含多个请求头。为确保视图返回JSON格式数据,需将'Accept'头设置为'application/json'。此外,为在视图层识别该请求为AJAX请求,应添加'X-Requested-With'头并设为'XMLHttpRequest'。

Fetch不会直接返回数据,而是返回一个Promise对象,该Promise在响应就绪时解决。为了获取数据,需使用链式Promise处理:第一个.then将响应转换为JSON对象;第二个.then则访问该JSON数据,进而执行如更新页面DOM等操作。

在视图层处理GET请求 我们需要一个Django视图来响应来自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会将数据字典序列化为JSON字符串并发送回前端,由前端的Promise链进行处理。至此,我们已能通过JavaScript利用GET请求中的数据来更新页面局部内容。

POST请求的配置与视图处理

POST请求

通过Fetch发出POST请求

与GET请求相比,发起POST请求需要配置更多的参数。


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

Fetch默认发起GET请求。若要发起POST请求,必须在配置对象中显式指定method为'POST'。

Credentials

需指定凭证的发送方式。若前端与后端托管在同一域名下,可使用默认值'same-origin',即仅当请求URL与Fetch调用来源相同时才发送用户凭证。若前后端分离部署,则需配置不同的凭证策略,并需考虑跨域资源共享(CORS)问题。

Headers

POST请求的'Accept'和'X-Requested-With'头与GET请求相同,但必须额外添加'X-CSRFToken'头以符合安全要求。

向Django发送POST请求时,必须包含CSRF令牌以防止跨站请求伪造攻击。Django文档提供了从csrftoken cookie中提取令牌的具体JavaScript代码。


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'头的内容添加到请求头中。

BODY

POST请求旨在向视图发送数据并可能更新数据库,因此需在Fetch调用中包含数据主体。若发送JSON数据,需添加body: JSON.stringify(data),其中data为待发送数据的JavaScript对象。除JSON外,正文也可包含文件或其他表单数据,具体可参考MDN文档。

从POST请求获得的响应处理方式与GET请求相同,均通过链式Promise进行解析。

在视图层处理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模块。解析后得到包含前端发送数据的字典,可通过键值访问具体数据。

获取请求数据后,即可执行用户期望的操作,例如创建新的模型实例或更新现有实例。

与GET请求类似,可使用JsonResponse及包含数据的字典将结果(如新创建或更新的模型对象、成功消息等)发送回前端页面。

AJAX请求的安全检查与版本兼容

确保请求是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()的逻辑中重构,该逻辑仅一行代码:


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))

注意事项与建议

一些重要注意事项

尽管Fetch是发起AJAX请求的便捷方式,但并非所有浏览器(如部分Internet Explorer版本)均支持。若需兼容IE,建议使用jQuery或XMLHttpRequest来发起AJAX请求。

AJAX请求应仅限于Django项目的局部更新。若发现需在多个模板中通过AJAX获取大量数据,建议考虑使用Django Rest Framework构建API。

概要

在Django项目中使用AJAX请求,可实现页面局部更新而无需重新加载整个页面。Fetch API使得添加此功能变得相对简单,且所需的JavaScript代码最少。正确且谨慎地使用AJAX,可提升页面响应速度,为用户提供更丰富的交互体验。

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

总结

到此这篇关于使用AJAX和Django获取数据的文章就介绍到这了,更多相关AJAX和Django获取数据内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。