2012-09-30 10 views
8

Estoy usando django-storages y sorl_thumbnail juntos y estoy usando Amazon S3 para archivos estáticos y de medios. Estoy usando un cubo con 2 carpetas, 1 para estático y 1 para medios.django-storages + sorl_thumbnail + S3 no funciona bien en conjunto (las URL no coinciden)

Aquí es mi config:

MEDIA_ROOT = '/media/' 
MEDIA_URL = 'https://s3.amazonaws.com/my-bucket/media/' 
STATIC_ROOT = '/static/' 
STATIC_URL = 'https://s3.amazonaws.com/my-bucket/static/' 
AWS_STORAGE_BUCKET_NAME = 'my-bucket' 
DEFAULT_FILE_STORAGE = 'my_lib.s3utils.MediaRootS3BotoStorage' 
STATICFILES_STORAGE = 'my_lib.s3utils.StaticRootS3BotoStorage' 

MediaRootS3BotoStorage y StaticRootS3BotoStorage se definen así:

StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static') 
MediaRootS3BotoStorage = lambda: S3BotoStorage(location='media') 

Cuando utilizo sorl_thumbnail, las miniaturas generadas se encuentran en el directorio correcto: https://s3.amazonaws.com/my-bucket/media/cache pero cuando sorl_thumbnail está tratando de recuperar una miniatura ya existente, la URL generada es: https://s3.amazonaws.com/my-bucket/cache, notará que la carpeta media se ha omitido.

¿Tiene alguna idea de cómo podría solucionarlo?

Sé que sólo pudiera utilizar Django almacenes y tienen mis archivos de medios estáticos y todo mezclado en mi cubo, pero eso es un poco demasiado sucia para mi gusto :)

Gracias!

Respuesta

17

que era capaz de hacer que funcione mediante la definición de MediaRootS3BotoStorage y StaticRootS3BotoStorage de la siguiente manera:

from storages.backends.s3boto import S3BotoStorage 
from django.conf import settings 

class StaticRootS3BotoStorage(S3BotoStorage): 
    """ 
    Storage for static files. 
    """ 

    def __init__(self, *args, **kwargs): 
     kwargs['location'] = 'static' 
     super(StaticRootS3BotoStorage, self).__init__(*args, **kwargs) 


class MediaRootS3BotoStorage(S3BotoStorage): 
    """ 
    Storage for uploaded media files. 
    """ 

    def __init__(self, *args, **kwargs): 
     kwargs['location'] = 'media' 
     super(MediaRootS3BotoStorage, self).__init__(*args, **kwargs) 

Este enlace puede ser útil https://github.com/jamstooks/django-s3-folder-storage

+1

Los métodos 'super()' en cada uno de los métodos '__init __()' anteriores están llamando a las clases incorrectas. Deben ser: 'super (StaticRootS3BotoStorage, auto) .__ init __ (* args, ** kwargs)' y 'super (MediaRootS3BotoStorage, auto) .__ init __ (* args, ** kwargs)' – niceguydave

1

tenía este mismo problema, pero me di cuenta de una manera de evitarlo.

puse mi DEFAULT_FILE_STORAGE de nuevo a storages.backends.s3boto.S3BotoStorage, de esa manera, cuando se buscó cache/ sería no se pierda, y todavía podía cargar todos mis archivos a media/ y python manage.py collectstatic todavía funciona correctamente porque todavía tengo que estableció como StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static') .

Espero que esto te ayude, porque este problema me estaba volviendo loco.

+0

¡gracias por su ayuda! Pero el resultado para mí cuando uso estas configuraciones es que los archivos estáticos van a la carpeta/static/en S3 pero todos los archivos cargados están en la carpeta raíz, no entran en/media /. ¿Alguna idea? –

+0

Disculpe la respuesta tardía, pero asegúrese de que en sus modelos esté utilizando 'UPLOAD_TO = 'media /''. Eso debería poner sus archivos cargados donde los desee. –

+0

Sí, supuse que lo estabas haciendo, pero preferiría no, de lo contrario se rompe el propósito de cómo funciona django :) ¡Gracias de todos modos! –

0

encontró que sorl-thumbnail es devolver el KV imagen previa url utilizando STATIC_URL (en la siguiente solicitud después de crear la miniatura inicial). Aparece MEDIA_URL no tiene efecto.

No es la mejor solución. Se agregó una regla de enrutamiento S3.

<RoutingRules> 
    <RoutingRule> 
    <Condition> 
     <KeyPrefixEquals>cache/</KeyPrefixEquals> 
    </Condition> 
    <Redirect> 
     <ReplaceKeyPrefixWith>media/cache/</ReplaceKeyPrefixWith> 
    </Redirect> 
    </RoutingRule> 
</RoutingRules> 
8

Tuve el mismo problema y la solución de Salma Hamed resultó ser la correcta para mí.

Antes teníamos

StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static') 
MediaRootS3BotoStorage = lambda: S3BotoStorage(location='media') 

que dio lugar a valores erróneos 'almacenamiento' en nuestra mesa thumbnail_kvstore.Esta definición lambda no crea una nueva clase y, por lo tanto, escribe (StaticRootS3BotoStorage()) devuelve 'storages.backends.s3boto.S3BotoStorage', que está escrito en la tabla. Debido a que estos valores de "almacenamiento" se utilizan para instanciar posteriormente el almacenamiento para obtener las URL de la imagen cuando se muestran, esto dio como resultado que se usara S3BotoStorage() para esto. Entonces el argumento de 'ubicación' se perdió.

La solución de Salma Hamed que define estos almacenes personalizados como clases corrige esto.

¡Gracias por eso!

+0

¿Recuerdas dónde aprendiste a usar la solución anterior de 'lambda: S3BotoStorage (location = 'static')'? Me gustaría publicar un comentario o corregirlo. – Flimm

Cuestiones relacionadas