Django-хранилища с несколькими ведрами S3 - программирование
Подтвердить что ты не робот

Django-хранилища с несколькими ведрами S3

Я использую AWS, и в моем приложении будут разные корзины. Я также использую Django-Storages. Есть ли способ указать, в какую корзину я хочу загрузить файл (например, в качестве параметра в функции Save() или как?)

Я видел это Django - Ошибка при импорте storages.backends, но я не понимаю, как его использовать?!

4b9b3361

Ответ 1

S3BotoStorage принимает имя сегмента в качестве параметра. Если он не указан, он будет использовать настройку AWS_STORAGE_BUCKET_NAME. Это означает, что если вы хотите сделать S3BotoStorage серверным хранилищем по умолчанию с DEFAULT_FILE_STORAGE тогда он должен использовать S3BotoStorage по умолчанию.

Однако вы также можете назначить хранилище на уровне поля:

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'))

Редактировать:

Комментарии выходят из-под контроля, поэтому я обновлю свой ответ. Изменение параметров серверной части хранилища на основе экземпляра - это не то, для чего был разработан API хранилища Django. Бэкэнд хранилища не знает об экземпляре модели, поскольку хранилища могут использоваться вне контекста модели, например со статическими файлами. Не совсем неразумно, но это не использование, которое Django или django-хранилища должны были решить. Я не ожидаю, что вы найдете каплю в хранилище, которая справится с этим за вас.

Документы описывают, как вы можете управлять файлами вручную: https://docs.djangoproject.com/en/1.9/topics/files/#storage-objects Как минимум вам нужно будет хранить корзину, где вы сохранили файл, чтобы вы могли можно найти позже, когда вы запросите модель.

Ответ 2

Другое решение, если вы хотите указать 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 будет сохранен в указанном вами ведре, где file_1 будет использовать ваш по умолчанию.

Ответ 3

Просто укажите другое имя ведра в settings.py с PRIVATE_BUCKET_NAME= 'bucket name'.

Создайте собственный класс, который переопределяет S3BotoStorage и который может быть сериализован в файлы миграции.

Создайте объект для класса s3_storage = S3MediaStorage() и отдайте его на хранение в поле file1 в MyModel

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)