具有多个S3存储桶的django存储

具有多个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

我正在使用AWS,我的应用程序中将有不同的存储桶。我还使用Django存储。是否有方法指定要将文件上载到哪个存储桶(例如,作为Save()函数中的参数或其他什么?)


我看到了,但我不明白该怎么用

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()
-获取存储桶名称的功能取决于型号选项。