2016-08-06 4 views
3

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

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

+0

привет @anurag, сделали мой ответ на который Флит дали щедроты работать для вас, а? – e4c5

ответ

5

Простейшим является подкласс 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 класса с нашего кода просто проверяя тип содержимого и имя, чтобы добавить пользовательские заголовки.

+0

Извините @flimm, этот ответ был довольно неосторожным усилием. Кажется, я сейчас разобрал все проблемы. В основном идея заключается в том, что вы преодолеваете метод _save, который является местом, которое лучше всего подходит для изменения заголовков и внесения изменений по мере необходимости. Оппозиция снова о неосторожном ness – e4c5

+0

Это прекрасно работает с одним оговоркой: он не будет устанавливать пользовательский заголовок Content-Type, потому что суперметод переопределит его. – Flimm

+0

Спасибо за щедрость @Flimm. Это оговорку можно преодолеть, скопировав остальную часть кода из _save и отредактировав этот бит, и избегая вызова супер. – e4c5

1
# 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' 
+0

В чем разница между этим ответом и ответом e4c5? Кроме того, он не работает, '_type' не определен. – Flimm

+0

ooh ... проверял источник 'storage' для возможного решения, забыл проверить prev. Ответ srry –

+0

Не беспокойтесь. :) '' '' – Flimm

0

Другие ответы о 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) 
Смежные вопросы