2011-10-08 20 views
27

Estoy intentando configurar django-compressor y django-staticfiles para que el CSS/Javascript comprimido y las imágenes se publiquen desde el S3 de Amazon.Cómo configurar django-compressor y django-staticfiles con Amazon's S3?

He logrado configurar archivos estáticos usando S3 como servidor, por lo que el comando collectstatic envía los archivos a S3 en lugar de a STATIC_ROOT.

Sin embargo, cuando trato de agregar django-compressor a la mezcla es donde todo parece derrumbarse para mí. Después del documentation en la configuración de almacenamientos remotos, he creado una subclase del back-end de almacenamiento, boto, así que copié el example al storage.py. Una vez que empiezo a utilizar este backend en caché, los archivos se copian en static_media y no en S3. Después de cargar la primera página, la carpeta CACHE aparece en S3 y en la carpeta static_media.

Configuración STATICFILES_STORAGE y COMPRESS_STORAGE de nuevo a clase S3 normal del boto (storages.backends.s3boto.S3BotoStorage) da lugar a los activos estáticos que se recoge en el depósito de S3 y ninguna carpeta static_media. Sin embargo tratando de recargar la página lanza el error:

Caught NotImplementedError while rendering: This backend doesn't support absolute paths. 

destacando {% compress css %} como la etiqueta y compressor/base.py como el origen.

El/staticfiles/s3 sección del compresor de mi settings.py:

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' 
AWS_ACCESS_KEY_ID = 'key' 
AWS_SECRET_ACCESS_KEY ='secret' 
AWS_STORAGE_BUCKET_NAME = 'my-bucket' 
S3_URL = 'http://my-bucket.s3.amazonaws.com/' 

MEDIA_ROOT = 'client_media' 
MEDIA_URL = '/media/' 
STATIC_ROOT = 'static_media' 
STATIC_URL = S3_URL 
ADMIN_MEDIA_PREFIX = S3_URL + 'admin/' 
STATICFILES_DIRS = (
    join(DIRNAME, 'static'), 
) 
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder', 
    'django.contrib.staticfiles.finders.AppDirectoriesFinder', 
    'compressor.finders.CompressorFinder', 
) 

COMPRESS_ENABLED = True 
COMPRESS_URL = S3_URL 
COMPRESS_ROOT = STATIC_ROOT 
COMPRESS_STORAGE = 'storage.CachedS3BotoStorage' 
STATICFILES_STORAGE = COMPRESS_STORAGE 

Entonces, ¿dónde estoy haciendo mal? ¿He configurado incorrectamente algo al usar el almacenamiento personalizado CachedS3BotoStorage?

Respuesta

9

Su configuración se ve correctamente. Debería mantener STATICFILES_STORAGE y COMPRESS_STORAGE establecidos en storage.CachedS3BotoStorage y no volver a storages.backends.s3boto.S3BotoStorage.

De acuerdo con this problema django-compressor, el problema está en la forma en que django-staticfiles guarda durante el proceso colecético (usando shutil.copy2). Este problema se corrigió en la versión más reciente de django-staticfiles, que se puede usar en lugar del que se envía con Django 1.3.

pip install django-staticfiles==dev 

Y en su settings.py, cambiar a la versión actualizada:

STATICFILES_FINDERS = (
    #"django.contrib.staticfiles.finders.FileSystemFinder", 
    #"django.contrib.staticfiles.finders.AppDirectoriesFinder", 
    "staticfiles.finders.FileSystemFinder", 
    "staticfiles.finders.AppDirectoriesFinder", 
    "compressor.finders.CompressorFinder", 
) 

INSTALLED_APPS = (
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    #'django.contrib.staticfiles', 
    'staticfiles', 
    #... 
) 

Después de ejecutar python manage.py collectstatic de nuevo, tanto el directorio de caché de Django-compresor y los archivos recopilados staticfiles deben aparecer en S3.

0

El uso de django_compressor==1.2 funcionó para mí. No estoy seguro de por qué necesita instalar django-staticfiles; sin embargo, todas las versiones de django_compressor excepto 1.2 tienen ese problema.

0

Después de muchos días de arduo trabajo e investigación, finalmente pude hacer esto y decidí escribir un detailed guide al respecto, que incluía cómo también se les podía cargar comprimidos con gzip.

Básicamente, usted tiene que hacer algunas cosas:

  1. Uso AWS_IS_GZIPPED = True
  2. Si su S3 se encuentra fuera de los Estados Unidos. Debe crear una clase personalizada S3Connection donde anule la variable DefaultHost en su url S3. Ejemplo s3-eu-west-1.amazonaws.com
  3. Si está utilizando un nombre de cubo con puntos, ejemplo subdomain.domain.tld. Es necesario establecer AWS_S3_CALLING_FORMAT = 'boto.s3.connection.OrdinaryCallingFormat'
  4. Usted tiene que fijar non_gzipped_file_content = content.file en su CachedS3BotoStorage

Ésta es la clase CachedS3BotoStorage que necesita:

class CachedS3BotoStorage(S3BotoStorage): 
    """ 
    S3 storage backend that saves the files locally, too. 
    """ 
    connection_class = EUConnection 
    location = settings.STATICFILES_LOCATION 
    def __init__(self, *args, **kwargs): 
     super(CachedS3BotoStorage, self).__init__(*args, **kwargs) 
     self.local_storage = get_storage_class(
      "compressor.storage.CompressorFileStorage")() 

def save(self, name, content): 
    non_gzipped_file_content = content.file 
    name = super(CachedS3BotoStorage, self).save(name, content) 
    content.file = non_gzipped_file_content 
    self.local_storage._save(name, content) 
    return name 

Tenga en cuenta que EUConnection es una clase personalizada donde hice DefaultHost a mi S3 ubicación. Consulte la guía mucho más larga y detallada para los almacenamientos personalizados completos y settings.py

Cuestiones relacionadas