2011-10-08 16 views
27

Sto provando a impostare django-compressor e django-staticfiles in modo che il CSS/Javascript compresso e le immagini siano servite da S3 di Amazon.Come configurare django-compressor e django-staticfiles con Amazon S3?

Sono riuscito a impostare i file statici utilizzando S3 come back-end, quindi il comando collectstatic invia i file a S3 anziché a STATIC_ROOT.

Tuttavia, quando si tenta di aggiungere django-compressor al mix è dove tutto sembra cadere a pezzi per me. Dopo lo documentation sulla configurazione di archivi remoti, ho creato una sottoclasse del backend di archiviazione, boto, quindi ho copiato lo example in storage.py. Una volta iniziato a utilizzare questo backend memorizzato nella cache, i file vengono copiati in static_media e non in S3. Dopo il caricamento della prima pagina, la cartella CACHE viene visualizzata su S3 e nella cartella static_media.

Impostazione STATICFILES_STORAGE e COMPRESS_STORAGE torna alla normalità classe S3 di Boto (storages.backends.s3boto.S3BotoStorage) risultati nelle attività statiche essere raccolti nel secchio S3 e nessuna cartella static_media. Tuttavia cercando di ricaricare la pagina genera l'errore:

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

evidenziando {% compress css %} come il tag e compressor/base.py come origine.

Il/staticfiles/sezione del compressore s3 della mia 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 

Allora, dove sto andando male? Ho configurato male qualcosa durante l'utilizzo dello spazio di archiviazione personalizzato CachedS3BotoStorage?

risposta

9

Le impostazioni sembrano corrette. È necessario mantenere entrambi STATICFILES_STORAGE e COMPRESS_STORAGE impostato su storage.CachedS3BotoStorage e non tornare a storages.backends.s3boto.S3BotoStorage.

In base al problema del django-compressore this, il problema riguarda il modo in cui i file django-staticfiles vengono salvati durante il processo collectstatic (utilizzando shutil.copy2). Questo problema è stato corretto nella versione più recente di django-staticfiles, che può essere utilizzata al posto di quella fornita con Django 1.3.

pip install django-staticfiles==dev 

E nel vostro settings.py, passare alla versione aggiornata:

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', 
    #... 
) 

Dopo l'esecuzione python manage.py collectstatic ancora una volta, sia la directory della cache da django-compressore e i file staticfiles raccolti dovrebbero mostrare su S3.

0

L'utilizzo di django_compressor==1.2 ha funzionato per me. Non sono sicuro del motivo per cui è necessario installare django-staticfile ma tutte le versioni di django_compressor tranne 1.2 hanno quel problema.

0

Dopo un sacco di giorni di duro lavoro e ricerca sono finalmente riuscito a farlo e ho deciso di scrivere un detailed guide su di esso, compreso come servirli anche zippato con gzip.

Fondamentalmente è necessario fare un paio di cose:

  1. Usa AWS_IS_GZIPPED = True
  2. Se il vostro S3 è al di fuori degli Stati Uniti. È necessario creare una classe personalizzata S3Connection in cui si esegue l'override della variabile DefaultHost nell'URL S3. Esempio s3-eu-west-1.amazonaws.com
  3. Se si sta utilizzando un nome bucket punteggiato, esempio subdomain.domain.tld. È necessario impostare AWS_S3_CALLING_FORMAT = 'boto.s3.connection.OrdinaryCallingFormat'
  4. È necessario impostare non_gzipped_file_content = content.file nella vostra CachedS3BotoStorage

Questa è la classe CachedS3BotoStorage è necessario:

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 

Nota che EUConnection è una classe personalizzata in cui ho impostato DefaultHost alla mia Posizione S3. Consulta la guida molto più lunga e dettagliata per completare archivi e impostazioni personalizzati.py