跳转到主要内容

Django项目私有媒体文件存储

项目描述

django-private-storage

https://github.com/edoburu/django-private-storage/actions/workflows/tests.yaml/badge.svg?branch=master https://img.shields.io/pypi/v/django-private-storage.svg https://img.shields.io/pypi/l/django-private-storage.svg https://img.shields.io/codecov/c/github/edoburu/django-private-storage/master.svg

此模块提供私有媒体文件存储,因此用户上传可以受到登录保护。

它使用Django存储API的内部功能,因此所有表单渲染和管理员集成都无需额外操作。

安装

pip install django-private-storage

配置

添加到设置中

INSTALLED_APPS += (
    'private_storage',
)

PRIVATE_STORAGE_ROOT = '/path/to/private-media/'
PRIVATE_STORAGE_AUTH_FUNCTION = 'private_storage.permissions.allow_staff'

添加到 urls.py

import private_storage.urls

urlpatterns += [
    path('private-media/', include(private_storage.urls)),
]

使用方法

在Django模型中添加 PrivateFileField

from django.db import models
from private_storage.fields import PrivateFileField

class MyModel(models.Model):
    title = models.CharField("Title", max_length=200)
    file = PrivateFileField("File")

PrivateFileField 还接受以下关键字参数

  • upload_to:在 PRIVATE_STORAGE_ROOT 中的可选子文件夹。

  • upload_subfolder:一个定义文件夹的函数,它接收当前的模型实例

  • content_types:允许的内容类型

  • max_file_size:字节数的最大文件大小。(1MB是1024 * 1024)

  • storage:要使用的存储对象,默认为private_storage.storage.private_storage

图片

您还可以使用PrivateImageField,它只允许您上传图片

from django.db import models
from private_storage.fields import PrivateImageField

class MyModel(models.Model):
    title = models.CharField("Title", max_length=200)
    width = models.PositiveSmallIntegerField(default=0)
    height = models.PositiveSmallIntegerField(default=0)
    image = PrivateFileField("Image", width_field='width', height_field='height')

PrivateImageField还接受以下kwargs,除了PrivateFileField

  • width_field:可选字段,用于存储图片的宽度

  • height_field:可选字段,用于存储图片的高度

其他主题

在Amazon S3上存储文件

PRIVATE_STORAGE_CLASS设置可以被重新定义,以指向不同的存储类。默认是private_storage.storage.files.PrivateFileSystemStorage,它使用PRIVATE_STORAGE_ROOT指向的私有媒体文件夹。

定义以下设置之一

PRIVATE_STORAGE_CLASS = 'private_storage.storage.s3boto3.PrivateS3BotoStorage'

AWS_PRIVATE_STORAGE_BUCKET_NAME = 'private-files'  # bucket name

这使用django-storages设置。将前缀AWS_替换为AWS_PRIVATE_。以下设置在没有相应的AWS_PRIVATE_...设置时被重用

  • AWS_ACCESS_KEY_ID

  • AWS_SECRET_ACCESS_KEY

  • AWS_S3_URL_PROTOCOL

  • AWS_S3_REGION_NAME

  • AWS_IS_GZIPPED

所有其他设置应使用AWS_PRIVATE_...设置明确定义。

默认情况下,所有管理中的URL都返回直接S3桶URL,启用查询参数认证。当AWS_PRIVATE_QUERYSTRING_AUTH = False时,所有文件下载都通过我们的PrivateFileView URL进行代理。此行为可以通过使用PRIVATE_STORAGE_S3_REVERSE_PROXY = True明确启用。

要启用加密,请配置AWS_PRIVATE_S3_ENCRYPTIONAWS_PRIVATE_S3_SIGNATURE_VERSION或使用

PRIVATE_STORAGE_CLASS = 'private_storage.storage.s3boto3.PrivateEncryptedS3BotoStorage'

确保在Amazon上生成加密密钥。

MinIO存储

定义以下设置之一

PRIVATE_STORAGE_CLASS = 'private_storage.storage.minio.PrivateMinioStorage'

MINIO_PRIVATE_STORAGE_MEDIA_BUCKET_NAME = 'private-files'
MINIO_PRIVATE_STORAGE_MEDIA_URL= '/private-files'

这使用django-minio-storage设置。将前缀MINIO_替换为MINIO_PRIVATE_。所有设置在没有相应的MINIO_PRIVATE_...设置时被重用。

  • MINIO_STORAGE_ENDPOINT

  • MINIO_STORAGE_ACCESS_KEY

  • MINIO_STORAGE_SECRET_KEY

  • MINIO_STORAGE_USE_HTTPS

  • MINIO_STORAGE_MEDIA_BUCKET_NAME

  • MINIO_STORAGE_MEDIA_URL

  • MINIO_STORAGE_AUTO_CREATE_MEDIA_BUCKET

  • MINIO_STORAGE_AUTO_CREATE_MEDIA_POLICY

  • MINIO_STORAGE_MEDIA_USE_PRESIGNED

  • MINIO_STORAGE_MEDIA_BACKUP_FORMAT

  • MINIO_STORAGE_ASSUME_MEDIA_BUCKET_EXISTS

  • MINIO_STORAGE_MEDIA_OBJECT_METADATA

与S3一样,您可以通过我们的PrivateFileView URL启用代理。只需指定PRIVATE_STORAGE_MINO_REVERSE_PROXY = True

定义访问规则

PRIVATE_STORAGE_AUTH_FUNCTION定义了哪些用户可以访问文件。默认情况下,这仅包括超级用户。

以下是一些可用的选项

  • private_storage.permissions.allow_authenticated

  • private_storage.permissions.allow_staff

  • private_storage.permissions.allow_superuser

您可以创建一个自定义函数,并使用它代替。该函数接收一个private_storage.models.PrivateFile对象,它有以下字段

  • request:Django请求。

  • storage:用于检索文件的存储引擎。

  • relative_name:存储中的文件名。

  • full_path:完整的文件系统路径。

  • exists():文件是否存在。

  • content_type:HTTP内容类型。

  • parent_object:仅在使用了PrivateStorageDetailView时设置。

通过对象ID检索文件

为实现更多基于对象的访问权限,创建一个提供下载的自定义视图。

from private_storage.views import PrivateStorageDetailView

class MyDocumentDownloadView(PrivateStorageDetailView):
    model = MyModel
    model_file_field = 'file'

    def get_queryset(self):
        # Make sure only certain objects can be accessed.
        return super().get_queryset().filter(...)

    def can_access_file(self, private_file):
        # When the object can be accessed, the file may be downloaded.
        # This overrides PRIVATE_STORAGE_AUTH_FUNCTION
        return True

以下类级别属性可以被重写

  • model:要获取的模型(包括SingleObjectMixin的所有其他属性)。

  • model_file_field:这应该指向用于存储文件的字段。

  • storage / get_storage():从其中读取文件的存储类。

  • server_class:用于生成HttpResponse / FileResponse的Python类。

  • content_disposition:可以是“inline”(在浏览器内显示)或“attachment”(保存为下载)。

  • content_disposition_filename / get_content_disposition_filename():覆盖下载的文件名。

优化大文件传输

在某些配置中,发送大文件可能效率不高。

在最坏的情况下,整个文件需要分块读取,并通过整个WSGI缓冲区、OS内核、Web服务器和代理服务器传输。实际上,整个文件在内存缓冲区中复制了几次。

有更有效的方法来传输文件,例如UNIX上的sendfile()系统调用。当WSGI服务器提供wsgi.file_handler支持时,Django会使用此功能。

在某些情况下,这种效果会被抵消,例如通过位于WSGI容器前面的本地HTTP服务器。一个典型的例子是在Nginx或Apache Web服务器后面运行Gunicorn。

对于这种情况,可以通过以下设置启用Web服务器的本地支持

对于Apache

PRIVATE_STORAGE_SERVER = 'apache'

这还需要安装并激活mod_xsendfile Apache模块。将以下XSendFile配置添加到您的conf.d配置文件中。

<virtualhost ...>
...
WSGIScriptAlias / ...
XSendFile On
XSendFilePath ... [path to where the files are, same as PRIVATE_STORAGE_ROOT]
...
</virtualhost>

对于Nginx

PRIVATE_STORAGE_SERVER = 'nginx'
PRIVATE_STORAGE_INTERNAL_URL = '/private-x-accel-redirect/'

在服务器配置中添加以下location块

location /private-x-accel-redirect/ {
  internal;
  alias   /path/to/private-media/;
}

对于非常旧的Nginx版本,您将不得不配置PRIVATE_STORAGE_NGINX_VERSION,因为Nginx版本在1.5.9之前(2014年发布)处理非ASCII文件名的方式不同。

其他Web服务器

PRIVATE_STORAGE_SERVER也可以指向一个点分隔的Python类路径。实现一个具有静态serve(private_file)方法的类。

使用多个存储

PrivateFileField接受一个storage关键字参数,因此您可以初始化多个private_storage.storage.PrivateStorage对象,每个对象从不同的locationbase_url提供文件。

例如

from django.db import models
from private_storage.fields import PrivateFileField
from private_storage.storage.files import PrivateFileSystemStorage

my_storage = PrivateFileSystemStorage(
    location='/path/to/storage2/',
    base_url='/private-documents2/'
)

class MyModel(models.Model):
    file = PrivateFileField(storage=my_storage)

然后创建一个视图来提供这些文件

from private_storage.views import PrivateStorageView
from .models import my_storage

class MyStorageView(PrivateStorageView):
    storage = my_storage

    def can_access_file(self, private_file):
        # This overrides PRIVATE_STORAGE_AUTH_FUNCTION
        return self.request.is_superuser

然后公开该URL

urlpatterns += [
    url('^private-documents2/(?P<path>.*)$', views.MyStorageView.as_view()),
]

贡献

此模块旨在通用。如果您对它有任何不满,或者认为它不够灵活,请告诉我们。我们很乐意改进它!

运行测试

我们使用tox在本地运行测试套件的不同版本(并使用travis-ci自动检查PR)。

要本地运行测试套件,请确保您的Python环境已安装tox和django

python3.6 -m pip install tox django

然后只需执行tox即可运行整个测试矩阵

tox

下载文件

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

源分发

django-private-storage-3.1.1.tar.gz (27.3 kB 查看哈希值)

上传时间

构建分发

django_private_storage-3.1.1-py3-none-any.whl (33.0 kB 查看哈希值)

上传时间 Python 3

由以下组织支持