Выборочно применять заголовки AWS при загрузке статических файлов с использованием django-хранилищ

Я хочу выборочно применять заголовки AWS на основе моего типа файла и шаблона имени файла при загрузке их в источник S3. Я использую django-хранилища с django 1.8.12

Я вижу настройку AWS_HEADERS в документации по django-хранилищам, но не могу найти способ применить эту настройку только к некоторым файлам. Я был бы признателен, если бы кто-то мог направить меня в этом

3 ответа

Самое простое - это создать подкласс storages.backends.s3boto.S3BotoStorage ввести требуемое поведение

from storages.backends.s3boto import S3BotoStorage

class MyS3Storage(S3BotoStorage):

    def _save(self, name, content):
        cleaned_name = self._clean_name(name)
        name = self._normalize_name(cleaned_name)

        _type, encoding = mimetypes.guess_type(name)
        content_type = getattr(content, 'content_type',
                           _type or self.key_class.DefaultContentType)

        # setting the content_type in the key object is not enough.
        self.headers.update({'Content-Type': content_type})


        if re.match('some pattern', cleaned_name) :
            self.headers.update({'new custome header': 'value'})

        if content_type == 'my/content_type':
            self.headers.update({'new custome header': 'value'})

        return super(MyS3Storage, self)._save(name, content)

Не забудьте отредактировать настройки и изменить определение хранилища файлов.

DEFAULT_FILE_STORAGE = 'myapp.MyS3Storage'

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

#  handlers.py
import mimetypes
from storages.backends.s3boto import S3BotoStorage
from django.conf import settings

class ManagedS3BotoStorage(S3BotoStorage):
    def _save(self, name, content):
        cleaned_name = self._clean_name(name)
        _type, encoding = mimetypes.guess_type(name)
        content_type = getattr(content, 'content_type',
                               _type or self.key_class.DefaultContentType)
        self.headers.update(self.get_headers(cleaned_name, content_type))
        return super(ManagedS3Storage, self)._save(name, content)

     def get_headers(cleaned_name, content_type):
         // if possible, load AWS_HEADERS_LIST from settings
         headers_list = settings.AWS_HEADERS_LIST
         // logic for updating headers & return headers  

# изменения в файле settings.py

DEFAULT_FILE_STORAGE = 'handlers.ManagedS3BotoStorage'

Другие ответы о S3BotoStorageэтот ответ о S3Boto3Storage (обратите внимание на 3 после Boto). Вы должны переопределить _save_content, как это:

class CustomBoto3Storage(S3Boto3Storage):
    def _save_content(self, obj, content, parameters):
        """We want .mp3 files to have the Content-Disposition header set to
        attachement in this example."""

        new_parameters = parameters.copy() if parameters else {}
        if new_parameters.get('ContentType') in ['audio/mpeg3', 'audio/x-mpeg-3', 'audio/mpeg']:
            new_parameters['ContentDisposition'] = 'attachment'
        return super()._save_content(obj, content, new_parameters)
Другие вопросы по тегам