如何在Django中将前端JavaScript上传的图片存储至AWS S3
Django实现上传图片到AWS S3完整方案
1. 安装依赖包
首先安装所需的第三方库:pip install django-storages boto3
2. 配置Django项目 settings.py
- 首先将
storages加入INSTALLED_APPS:
INSTALLED_APPS = [ # 其他原有应用 'storages', ]
- 追加AWS相关配置:
# AWS 认证信息,建议通过环境变量读取,不要硬编码 AWS_ACCESS_KEY_ID = "你的AWS访问密钥ID" AWS_SECRET_ACCESS_KEY = "你的AWS秘密访问密钥" # S3 桶配置 AWS_STORAGE_BUCKET_NAME = "你的S3桶名称" AWS_S3_REGION_NAME = "你的桶所在区域,比如ap-northeast-1" AWS_S3_FILE_OVERWRITE = False # 重名文件不覆盖,自动加后缀 AWS_DEFAULT_ACL = "public-read" # 按需设置,如果需要图片可公开访问就加这个 # 设置默认文件存储为S3 DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
3. 后端视图逻辑编写
写一个接收文件上传的接口,示例基于函数视图:
from django.http import JsonResponse from django.views.decorators.http import require_http_methods from django.views.decorators.csrf import csrf_exempt from .models import YourImageModel # 如果你需要把图片记录存在数据库的话 # 如果前端跨域或者未带csrf token可以临时加这个装饰器,生产环境建议正确配置csrf @csrf_exempt @require_http_methods(["POST"]) def upload_image(request): if 'image' not in request.FILES: return JsonResponse({"code":400,"msg":"未上传图片"}, status=400) image_file = request.FILES['image'] # 方式1:存到数据库模型(模型中ImageField会自动把文件存到S3) # image_record = YourImageModel.objects.create(image=image_file) # 方式2:直接保存到S3,不存数据库记录 from django.core.files.storage import default_storage file_path = default_storage.save(image_file.name, image_file) file_url = default_storage.url(file_path) return JsonResponse({"code":200,"msg":"上传成功", "image_url": file_url})
如果用模型存储,你的模型定义示例:
from django.db import models class YourImageModel(models.Model): image = models.ImageField(upload_to="uploads/") # upload_to是S3桶内的存储路径前缀 create_time = models.DateTimeField(auto_now_add=True)
4. 补全前端上传逻辑
你当前的前端代码只有文件选择和预览功能,需要补充提交上传的逻辑,示例如下:
// 给文件选择控件绑定事件 document.getElementById('files').addEventListener('change', handleFileSelect, false); let selectedFiles = []; // 修改原来的handleFileSelect,把选中的文件存起来 function handleFileSelect (evt) { selectedFiles = evt.target.files; // 保存选中的文件列表 // 原有预览逻辑不变 for (const file of evt.target.files) { const span = document.createElement('span'); const src = URL.createObjectURL(file); span.innerHTML = `<img style="height: 75px; border: 1px solid #000; margin: 5px"` + `src="${src}" title="${escape(file.name)}">`; document.getElementById('list').insertBefore(span, null) } } // 新增提交上传函数,绑定到你的上传按钮点击事件 function uploadFiles() { const formData = new FormData(); // 把所有选中的文件加入formData,这里如果是单文件上传直接加第一个就行 for (let i=0; i<selectedFiles.length; i++) { formData.append('image', selectedFiles[i]); } // 发请求到后端接口 fetch('/你的上传接口路径/', { method: 'POST', body: formData }).then(res => res.json()) .then(data => { if(data.code === 200) { console.log('上传成功,图片地址:', data.image_url); } else { alert('上传失败:' + data.msg); } }) }
注意事项
- AWS密钥不要硬编码在代码中,建议使用系统环境变量或者.env文件读取
- 需要提前配置S3桶的CORS规则,允许你的前端域名跨域访问
- 建议前后端都添加文件类型、大小校验,避免上传非法文件
- S3桶的权限不要开过大,仅开放必要的读写权限即可
内容的提问来源于stack exchange,提问作者Bill
相关产品推荐
相关产品推荐

