具有多个S3存储桶的django存储
我正在使用AWS,我的应用程序中将有不同的存储桶。我还使用Django存储。是否有方法指定要将文件上载到哪个存储桶(例如,作为Save()函数中的参数或其他什么?)具有多个S3存储桶的django存储,django,amazon-web-services,python-django-storages,Django,Amazon Web Services,Python Django Storages,我正在使用AWS,我的应用程序中将有不同的存储桶。我还使用Django存储。是否有方法指定要将文件上载到哪个存储桶(例如,作为Save()函数中的参数或其他什么?) 我看到了,但我不明白该怎么用 S3BotoStorage将bucket名称作为参数。如果未给出,它将使用AWS\u存储\u存储桶\u名称设置。这意味着,如果要使S3BotoStorage成为具有default\u FILE\u存储的默认存储后端,则必须使用默认存储桶 但是,您也可以在字段级别分配存储: from django.db
我看到了,但我不明白该怎么用
S3BotoStorage
将bucket名称作为参数。如果未给出,它将使用AWS\u存储\u存储桶\u名称
设置。这意味着,如果要使S3BotoStorage
成为具有default\u FILE\u存储的默认存储后端,则必须使用默认存储桶
但是,您也可以在字段级别分配存储:
from django.db import models
from storages.backends.s3boto import S3BotoStorage
class MyModel(models.Model):
file_1 = models.FileField() # Uses default storage
file_2 = models.FileField(storage=S3BotoStorage(bucket='other-bucket'))
编辑:
评论越来越失控,所以我会更新我的答案。在实例基础上更改存储后端的参数不是Django存储API设计的目的。存储后端不知道模型实例,因为存储可以在模型上下文之外使用,例如与静态文件一起使用。这并非完全不合理,但Django或Django storages并不打算解决这一问题。我不希望您在存储后端找到一个可以为您处理此问题的插件
这些文档描述了如何手动管理文件:您至少需要将保存文件的bucket存储在某个位置,以便以后查询模型时可以找到它。另一种解决方案如果要在运行时指定bucket,可以在调用模型上的save()方法之前指定
按照上述示例:
from django.db import models
from storages.backends.s3boto import S3BotoStorage
class MyModel(models.Model):
file_1 = models.FileField() # Uses default storage
file_2 = models.FileField()
保存模型时,可以在视图中指定该字段上的存储
my_file_model = MyModel()
my_file_model.file_2.storage = S3BotoStorage(bucket="your-bucket-name")
my_file_model.save()
这样,文件_2将保存在指定文件_1将使用默认存储桶的存储桶中。只需在settings.py中用PRIVATE_bucket_name=“bucket name”提及另一个存储桶名称即可
创建一个自定义类,该类重写S3BOToRage,并且可以序列化为迁移文件
为类s3\u storage=S3MediaStorage()
创建一个对象,并将其交给MyModel中的storage in file1字段
from storages.backends.s3boto import S3BotoStorage
from django.conf import settings
@deconstructible
class S3MediaStorage(S3BotoStorage):
def __init__(self, *args, **kwargs):
kwargs['bucket'] = getattr(settings, 'PRIVATE_BUCKET_NAME')
super(S3MediaStorage, self).__init__(*args, **kwargs)
s3_storage = S3MediaStorage()
class MyModel(models.Model):
file = models.FileField()
file1 = models.FileField(storage=s3_storage)
对于S3boto3存储,请使用以下命令:
media_file = models.FileField('media file', storage=S3Boto3Storage(bucket_name='media_bucket'), upload_to='media', blank=True)
美好的所以我不需要像这里所示覆盖?我可以像你刚才给我看的那样把桶递过来?!是的,对于这个用例,您不需要,因为您可以传递bucket名称。快速问号:在答案中,您是在静态中传递bucket名称。我们有机会通过吗?由于bucket名称将在运行时解析…不在模型定义中。为此,您需要一个子类S3BotoStorage
,可能还需要FileField
,具体取决于您在运行时解析bucket名称的方式。如果我想执行例如MyObject.save(bucket\u name),其中bucket\u name是一个变量,该怎么办。。。我该怎么做?!这很酷,但在分配新存储系统之前,请小心分配文件。否则默认存储将覆盖您的自定义存储。如果这是一个愚蠢的问题,我很抱歉,我是django的新手。您建议如何为上面的示例编写视图,我们不能简单地将其保存在模型中吗?我使用此方法并覆盖save()
:defsave(self,*args,**kwargs):self.file_field.storage=MyS3Boto3Storage(bucket\u name=self.bucket\u name())super().save(*args,**kwargs)
self.bucket\u name()
-获取存储桶名称的功能取决于型号选项。