【Django】后端CORS配置方法 前端fetch出错 无法获取数据

本文介绍了在前后端分离项目中,由于跨域导致的Django后端无法获取数据的问题。解决方案是通过配置Django的CORS设置,包括安装django-cors-headers库并在settings.py中添加相应配置。正确设置后,前端fetch请求可以成功获取数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

开发前后端分离项目,并且前后端服务器需要跨域来交互,直接用fetch会出问题,后端Django无法获取数据。

配置方法

前端fetch使用mode: 'cors'

后端Django,安装django-cors-headers
settings.py中设置:

INSTALLED_APPS = [
    'corsheaders',
]

MIDDLEWARE = [
    #...,
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    #...,
]

# 允许携带credentials,即cookies(只会带该域名的cookies哦)。
CORS_ALLOW_CREDENTIALS = True
# If True, cookies will be allowed to be included in cross-site HTTP requests. Defaults to False.
# Note: in Django 2.1 the SESSION_COOKIE_SAMESITE setting was added, set to 'Lax' by default, which
# will prevent Django's session cookie being sent cross-domain. Change it to None to bypass this 
# security restriction.

# 设置Allow all虽然简单粗暴,但是并不推荐,可能有安全风险。曾经的版本该配置叫CORS_ORIGIN_ALLOW_ALL,效果相同。默认值False
CORS_ALLOW_ALL_ORIGINS = True
# 推荐方式1,可以这样指定域名
CORS_ALLOWED_ORIGINS = [
    "https://example.com",
    "https://sub.example.com",
    "http://localhost:8080",
    "http://127.0.0.1:9000"
]
# 推荐方式2,正则匹配域名
CORS_ALLOWED_ORIGIN_REGEXES = [
    r"^https://\w+\.example\.com$",
]

# 设置允许的methods。以下是默认值
CORS_ALLOW_METHODS = [
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
]

# 设置允许的headers。以下是默认值
CORS_ALLOW_HEADERS = [
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
]

注意corsheaders.middleware.CorsMiddleware必须放在django.middleware.common.CommonMiddleware的上面。
然后就可以看到数据啦!

更多django-cors-headers配置项,可参考:
https://pypi.org/project/django-cors-headers/
https://github.com/adamchainz/django-cors-headers

<think>好的,我现在需要帮助用户将之前的JavaScript ECharts代码与Django后台集成,使用Python获取数据。用户之前已经得到了关于如何优化前端代码的建议,现在他们想了解如何从Django后端获取数据来动态更新图表。 首先,我要确定用户的需求。他们可能已经有一个Django项目,现在需要后端提供数据给前端的ECharts图表。用户可能对Django的MTV模式不太熟悉,或者不清楚如何将数据从视图传递到模板。 接下来,我需要考虑如何构造回答。可能需要分步骤讲解:创建Django视图、配置URL、模板渲染数据,以及前端的Ajax请求。用户可能需要具体的代码示例,所以需要提供详细的代码片段,并解释每个部分的作用。 还要注意用户提到的使用Python从Django后台获取数据,这可能包括如何从数据库查询数据,并将其转换为JSON格式。可能需要提到使用Django的模型和ORM,比如通过models定义数据模型,然后在视图中查询数据。 另外,用户之前的前端代码中使用的是JavaScript变量v1和v2,现在需要将这些变量替换为从后端获取的数据。需要解释如何在模板中使用Django的模板变量,或者通过Ajax动态获取数据,后者更适合实时更新。 可能还需要提到安全性问题,比如CSRF保护,当使用POST请求获取数据时,需要处理CSRF token。不过,如果是GET请求,可能不需要,但最好还是提到这一点。 另外,用户可能需要图表在页面加载时自动获取数据,或者在某个事件触发时更新。需要给出两种方式的示例,比如页面加载时初始化,以及通过按钮点击刷新数据。 还需要考虑数据格式,确保后端返回的数据结构符合前端ECharts的要求。例如,返回一个包含v1和v2的JSON对象,前端解析后更新图表。 最后,要确保整个流程清晰,步骤明确,用户能够按照步骤一步步实现集成。可能需要检查是否有遗漏的步骤,比如URL配置是否正确,视图函数是否正确处理请求,以及前端是否正确处理响应。</think>以下是基于 Django 后端 + 前端 ECharts 的完整数据集成方案,分为 **Python 后端**和 **前端 JavaScript** 两部分实现: --- ### **一、Django 后端实现** #### 1. 定义数据模型 (models.py) ```python from django.db import models class RepairRecord(models.Model): STATUS_CHOICES = [ ('closed', '已结算'), ('open', '未结算') ] status = models.CharField(max_length=10, choices=STATUS_CHOICES) created_at = models.DateTimeField(auto_now_add=True) ``` #### 2. 编写视图函数 (views.py) ```python from django.http import JsonResponse from .models import RepairRecord def get_repair_rate(request): # 从数据库统计数据 closed_count = RepairRecord.objects.filter(status='closed').count() open_count = RepairRecord.objects.filter(status='open').count() # 计算闭环率 total = closed_count + open_count close_rate = round((closed_count / total * 100), 2) if total > 0 else 0 # 返回JSON数据 return JsonResponse({ 'v1': closed_count, 'v2': open_count, 'close_rate': close_rate }) ``` #### 3. 配置路由 (urls.py) ```python from django.urls import path from . import views urlpatterns = [ path('api/repair-rate/', views.get_repair_rate, name='repair-rate-api'), ] ``` --- ### **二、前端集成方案** #### 1. 基础模板渲染 (HTML) ```html <div id="echart2" style="width: 600px; height: 400px;"></div> <script> // 直接从Django模板变量初始化(适用于首屏加载) var initialData = {{ repair_data|safe }}; // 需要在视图中传递context </script> ``` #### 2. 动态Ajax请求(推荐方式) ```javascript function echarts_2() { // 初始化图表 var myChart = echarts.init(document.getElementById('echart2')); // 发起Ajax请求获取数据 fetch('/api/repair-rate/') .then(response => response.json()) .then(data => { var option = { series: [{ type: 'pie', data: [ {value: data.v1, name: '已结算'}, {value: data.v2, name: '未结算'} ], label: { formatter: data.close_rate + '%' } }] }; myChart.setOption(option); }); // 窗口自适应 window.addEventListener("resize", () => myChart.resize()); } ``` --- ### **三、Django视图数据传递(可选方案)** #### 1. 服务端渲染方式 (views.py) ```python from django.shortcuts import render def dashboard(request): closed = RepairRecord.objects.filter(status='closed').count() open = RepairRecord.objects.filter(status='open').count() return render(request, 'dashboard.html', { 'repair_data': { 'v1': closed, 'v2': open, 'close_rate': round(closed / (closed + open) * 100, 2) } }) ``` #### 2. 模板中使用 (dashboard.html) ```javascript var myChart = echarts.init(document.getElementById('echart2')); var option = { series: [{ data: [ {value: {{ repair_data.v1 }}, name: '已结算'}, {value: {{ repair_data.v2 }}, name: '未结算'} ] }] }; myChart.setOption(option); ``` --- ### **四、关键技术点说明** 1. **数据流架构** $$ \text{数据库} \rightarrow \text{Django ORM} \rightarrow \text{JSON API} \rightarrow \text{ECharts} $$ 2. **性能优化建议** - 添加数据库查询缓存: ```python from django.core.cache import cache def get_repair_rate(request): cache_key = 'repair_stats' data = cache.get(cache_key) if not data: # ...数据库查询... cache.set(cache_key, data, timeout=300) # 缓存5分钟 return JsonResponse(data) ``` - 使用 `select_related`/`prefetch_related` 优化关联查询 3. **安全增强** - 添加API访问频率限制: ```python from django.views.decorators.cache import cache_page @cache_page(60 * 5) # 5分钟缓存 def get_repair_rate(request): # ... ``` - 启用CORS头部(如果跨域) --- ### **五、扩展应用场景** 1. **实时更新** 通过WebSocket实现数据推送: ```python # consumers.py from channels.generic.websocket import AsyncWebsocketConsumer class RepairStatsConsumer(AsyncWebsocketConsumer): async def connect(self): await self.accept() while True: data = get_live_data() # 自定义数据获取 await self.send(json.dumps(data)) await asyncio.sleep(60) # 每分钟推送 ``` 2. **历史趋势图** 添加时间范围查询参数: ```python # views.py def get_repair_rate(request): start_date = request.GET.get('start') end_date = request.GET.get('end') queryset = RepairRecord.objects.all() if start_date and end_date: queryset = queryset.filter(created_at__range=[start_date, end_date]) # ... ``` --- 通过以上方案,可以实现从 Django 数据库到 ECharts 可视化图表的完整数据链路。具体选择服务端渲染还是 API 动态加载,可根据项目的实时性要求决定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hull Qin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值