2012-09-30 21 views
8

Używam Django-Storages i Sorl_thumbnail razem i używam Amazon S3 dla plików statycznych i multimedialnych. Używam jednego wiadra z 2 folderami, 1 dla statycznego i 1 dla multimediów.django-storages + sorl_thumbnail + S3 nie działa dobrze razem (niedopasowanie adresów URL)

Oto mój 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 i StaticRootS3BotoStorage są zdefiniowane następująco:

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

Kiedy używam sorl_thumbnail, miniatury generowane są umieszczone w odpowiednim katalogu: https://s3.amazonaws.com/my-bucket/media/cache ale kiedy sorl_thumbnail próbuje odzyskać już istniejącą miniaturę, generowany URL to: https://s3.amazonaws.com/my-bucket/cache, zauważysz, że folder media został pominięty.

Czy masz pojęcie, jak mogę to naprawić?

wiem, może po prostu użyć Django magazyny i mają moje statyczne i plików multimedialnych wszystko pomieszane w moim wiadrze, ale to nieco zbyt brudny na mój gust :)

dziękuję!

Odpowiedz

17

udało mi się zrobić to praca definiując MediaRootS3BotoStorage i StaticRootS3BotoStorage następująco:

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) 

Ten link może być pomocne https://github.com/jamstooks/django-s3-folder-storage

+1

Metody 'super()' dla każdej z powyższych metod '__init __()' wywołują niewłaściwe klasy. Powinny one być: 'Super (StaticRootS3BotoStorage, self) .__ startowych __ (* args, ** kwargs)' i 'Super (MediaRootS3BotoStorage, self) .__ startowych __ (* args, ** kwargs)' – niceguydave

1

miałem to dokładnie taki sam problem, ale ja wymyśliliśmy sposób wokół niego.

mogę ustawić DEFAULT_FILE_STORAGE powrotem do storages.backends.s3boto.S3BotoStorage, że sposób, gdy wyglądało na cache/ byłoby nie brakuje, a ja nadal mógłby przesłać wszystkie moje pliki do media/ i python manage.py collectstatic nadal działa poprawnie, ponieważ nadal mam ten zestaw jako StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static') .

Mam nadzieję, że ci to pomoże, ponieważ ten problem doprowadzał mnie do szaleństwa.

+0

dziękuję za pomoc! Ale wynik dla mnie, gdy korzystam z tych ustawień to pliki statyczne do folderu/static/na S3, ale wszystkie przesłane pliki znajdują się w folderze głównym, nie wchodzą do/media /. Dowolny pomysł? –

+0

Przepraszamy za opóźnioną odpowiedź, ale upewnij się, że w modelach używasz 'UPLOAD_TO = 'media /''. To powinno umieścić twoje przesłane pliki tam, gdzie chcesz. –

+0

Tak, domyśliłem się, że to robisz, ale wolałbym nie, w przeciwnym razie po prostu łamie cel tego, jak działa django :) Dziękuję i tak! –

0

Znaleziony że sorl-thumbnail jest zwrócenie pamięci podręcznej KV obraz url przy użyciu STATIC_URL (przy następnym żądaniu po utworzeniu początkowej miniatury). Pojawia się MEDIA_URL nie ma wpływu.

Nie najlepsze rozwiązanie. Dodano regułę routingu S3.

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

Miałem ten sam problem, a rozwiązanie Salmy Hamed okazało się dla mnie właściwym rozwiązaniem.

Przed mieliśmy

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

które doprowadziły do ​​błędnych wartości „przechowywanie” w naszym stole thumbnail_kvstore.Ta definicja lambda nie tworzy nowej klasy, a zatem typ (StaticRootS3BotoStorage()) zwraca 'storages.backends.s3boto.S3BotoStorage', która jest zapisana w tabeli. Ponieważ te wartości "pamięci" są używane do utworzenia później pamięci w celu uzyskania adresów URL obrazów podczas wyświetlania, w wyniku tego S3BotoStorage() do tego zostanie użyte. Tak więc argument "lokalizacja" został utracony.

Rozwiązanie Salma Hamed, które definiuje te niestandardowe magazyny, jak klasy to rozwiązują.

Dzięki za to!

+0

Czy pamiętasz, gdzie nauczyłeś się używać poprzedniego rozwiązania 'lambda: S3BotoStorage (location = 'static')'? Chciałbym zamieścić komentarz lub poprawić go. – Flimm