我们目前在一个Django 1.11项目中使用AWS S3存储桶作为媒体文件的存储方式(使用django-storages库中的S3BotoStorage)。相关代码如下:
# storage.py
from storages.backends.s3boto import S3BotoStorage
class MediaRootS3BotoStorage(S3BotoStorage):
"""Storage for uploaded media files."""
bucket_name = settings.AWS_MEDIA_STORAGE_BUCKET_NAME
custom_domain = domain(settings.MEDIA_URL)
# common_settings.py
DEFAULT_FILE_STORAGE = 'storage.MediaRootS3BotoStorage'
AWS_MEDIA_STORAGE_BUCKET_NAME = 'xxxxxxxxxxxxxxxx'
MEDIA_URL = "//media.example.com/"
# models.py
import os
import uuid
from django.db import models
from django.utils import timezone
from django.utils.module_loading import import_string
def upload_to_unique_filename(instance, filename):
try:
extension = os.path.splitext(filename)[1]
except Exception:
extension = ""
now = timezone.now()
return f'resume/{now.year}/{now.month}/{uuid.uuid4()}{extension}'
class Candidate(models.Model):
[...]
resume = models.FileField(
storage=import_string(settings.DEFAULT_PRIVATE_FILE_STORAGE)(),
upload_to=upload_to_unique_filename,
)
[...]
问题在于存储桶键在设置文件中是硬编码的,由于有多个开发人员和一个演示环境,所有为测试/QA目的上传的垃圾文件最终都会与真正的生产数据一起上传到同一个S3存储桶中。
一个明显的解决方案是在“staging_settings.py”和“development_settings.py”文件中覆盖“AWS_MEDIA_STORAGE_BUCKET_NAME”,但这将使得生产数据在演示和测试实例上不可用。为了使其工作,我们需要以某种方式将生产存储桶与开发/演示存储桶同步,但我不确定如何高效且无缝地完成此操作。
另一个选择是在开发和演示环境中使用本地文件系统进行媒体存储。这也需要下载大量媒体文件,并将栈的一部分(django-storages和S3 API)从测试/QA过程中排除。
如何处理这个问题?在同一个存储桶中混合测试和生产媒体文件是一个问题吗(在开始考虑如何处理它之前,我很确定它是一个问题)?一般来说,有关分离开发/演示/生产云存储的最佳实践是什么?