跳转到主要内容

Django和Amazon S3的轻量级文件上传输入。

项目描述

django-s3file

为Django和Amazon S3提供轻量级文件上传输入。

Django-S3File允许您直接将文件上传到AWS S3,从而有效地绕过您的应用程序服务器。这有助于您避免因大文件上传而产生的长时间运行请求。如果您在AWS Lambda或Heroku上运行服务,并且有严格的请求限制,这将特别有用。

PyPi Version Test Coverage GitHub license

功能

  • 轻量级:少于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-storagesS3Boto3Storage或启用了虚拟的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'

项目详情


发布历史 发布通知 | RSS源

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

django_s3file-5.5.7.tar.gz (14.6 kB 查看哈希值)

上传于

构建分发

django_s3file-5.5.7-py3-none-any.whl (14.9 kB 查看哈希值)

上传于 Python 3

由以下支持