Django和Amazon S3的轻量级文件上传输入。
项目描述
django-s3file
为Django和Amazon S3提供轻量级文件上传输入。
Django-S3File允许您直接将文件上传到AWS S3,从而有效地绕过您的应用程序服务器。这有助于您避免因大文件上传而产生的长时间运行请求。如果您在AWS Lambda或Heroku上运行服务,并且有严格的请求限制,这将特别有用。
功能
- 轻量级:少于200行
- 无JavaScript或Python依赖(无jQuery)
- 易于集成
- 与内置组件相同
- 可扩展的JavaScript API
给程序员的话
sequenceDiagram
autonumber
actor Browser
participant S3
participant Middleware
Browser->>Django: GET form view
activate Django
Django->>Browser: RESPONSE w/ presigned POST URL & signed middleware key
deactivate Django
Browser->>S3: POST large file
activate S3
S3->>Browser: RESPONSE AWS S3 key
Browser->>Middleware: POST AWS S3 key (signed)
activate Middleware
Middleware->>S3: GET AWS S3 key
S3->>Middleware: RESPONSE large file promise
deactivate S3
Middleware->>Django: request incl. large file promise
deactivate Middleware
activate Django
opt only if files is procssed by Django
Django-->>S3: GET large file
activate S3
S3-->>Django: RESPONSE large file
deactivate S3
end
Django->>Browser: RESPONSE success
deactivate Django
简而言之,我们可以完全绕过Django,让AWS处理上传或任何处理。当然,如果您想在Django中处理文件,您也可以像以前一样这样做,同时增加了文件在数据中心内部提供服务的优势。
安装
确保您已正确设置了Amazon S3存储。
只需使用pip
安装S3file。
pip install django-s3file
# or
pipenv install django-s3file
在设置中添加S3File应用程序和中间件
# settings.py
INSTALLED_APPS = (
'...',
's3file',
'...',
)
MIDDLEWARE = (
'...',
's3file.middleware.S3FileMiddleware',
'...',
)
用法
S3File会自动替换Django的ClearableFileInput
小部件,您无需修改任何代码。
ClearableFileInput
小部件仅在将DEFAULT_FILE_STORAGE
设置为您设置的django-storages
的S3Boto3Storage
或启用了虚拟的FileSystemStorage
时自动替换。
设置AWS S3存储桶
上传文件夹
将S3文件上传到单个文件夹。文件在保存到upload_to
位置后,由Django进行移动。
建议为该文件夹设置过期策略,以确保旧的、未使用的文件上传不会积累并产生费用。
默认文件夹名称为:tmp/s3file
。您可以通过修改S3FILE_UPLOAD_PATH
设置来更改它。
CORS策略
您需要允许所有来源的POST
请求。只需将以下内容添加到您的CORS策略中。
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"POST"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [],
"MaxAgeSeconds": 3000
}
]
进度条
S3File会发出进度信号,可用于显示某种类型的进度条。名为progress
的信号既针对每个单独的文件输入,也针对整个表单。
进度信号包含以下详细信息
console.log(event.detail)
{
progress: 0.4725307607171312 // total upload progress of either a form or single input
loaded: 1048576 // total upload progress of either a form or single input
total: 2219064 // total bytes to upload
currentFile: File {…} // file object
currentFileName: "text.txt" // file name of the file currently uploaded
currentFileProgress: 0.47227834703299176 // upload progress of that file
originalEvent: ProgressEvent {…} // the original XHR onprogress event
}
以下示例实现了用于整个表单上传进度的Bootstrap进度条。
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
</div>
(function () {
var form = document.getElementsByTagName('form')[0]
var progressBar = document.getElementsByClassName('progress-bar')[0]
form.addEventListener('progress', function (event) {
// event.detail.progress is a value between 0 and 1
var percent = Math.round(event.detail.progress * 100)
progressBar.setAttribute('style', 'width:' + percent + '%')
progressBar.setAttribute('aria-valuenow', percent)
progressBar.innerText = percent + '%'
})
})()
在开发中使用S3File
在开发中使用S3File很有帮助,尤其是如果您想使用上面描述的进度信号。因此,S3File附带了一个AWS S3模拟后端。它的工作方式与真实的S3存储后端相似。如果DEFAULT_FILE_STORAGE
设置设置为FileSystemStorage
,则会自动启用。
为了防止用户在生产中意外使用FileSystemStorage
和不安全的S3模拟后端,还有一个额外的部署检查,如果在运行Django的部署检查套件时出错,则会报错。
python manage.py check --deploy
我们建议始终将部署检查套件作为您部署管道的一部分运行。
上传多个文件
Django对上传多个文件的支持有限。S3File完全支持此功能。自定义中间件确保文件可以通过request.FILES
访问,尽管它们是直接上传到AWS S3,而不是您的Django应用程序服务器。
使用优化的S3Boto3Storage
由于S3Boto3Storage
支持从任何其他fileobj存储数据,它使用通用的_save
函数。这导致前端将文件上传到S3,然后逐字节复制以执行移动操作,只是为了重命名上传的对象。对于大文件,这会导致用户额外的加载时间。
这就是为什么S3File在storages_optimized.S3OptimizedUploadStorage
中提供了一个此方法的优化版本。它使用更高效的S3 copy
方法,因为我们知道我们只从S3的一个位置复制到另一个位置。
from s3file.storages_optimized import S3OptimizedUploadStorage
class MyStorage(S3OptimizedUploadStorage): # Subclass and use like any other storage
default_acl = 'private'
项目详情
下载文件
下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。