2012-09-30 32 views
8

我一起使用django-storage和sorl_thumbnail,我使用Amazon S3作爲靜態和媒體文件。我使用一個存儲桶和兩個文件夾,其中1個用於靜態,1個用於存儲媒體。django-storages + sorl_thumbnail + S3在一起工作不正常(URLs不匹配)

這裏是我的配置:

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' 

MediaRootS3BotoStorageStaticRootS3BotoStorage被這樣定義:

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

當我使用sorl_thumbnail,生成位於正確的目錄縮略圖:https://s3.amazonaws.com/my-bucket/media/cache但是當sorl_thumbnail正試圖檢索已經存在的縮略圖,生成的URL爲:https://s3.amazonaws.com/my-bucket/cache,您會注意到media文件夾被省略。

你有什麼想法我可以解決這個問題嗎?

我知道我可以只使用Django的存儲器,並有我的靜態和媒體文件都在我的桶混了,但是這是我的口味:)

謝謝你有點太骯髒!

回答

17

我是能夠使通過定義MediaRootS3BotoStorageStaticRootS3BotoStorage它的工作方式如下:

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) 

此鏈接可以幫助https://github.com/jamstooks/django-s3-folder-storage

+1

上面每個'__init __()'方法的'super()'方法都調用錯誤的類。 他們應該是: '超(StaticRootS3BotoStorage,個體經營).__的init __(* ARGS,** kwargs)' 和 '超(MediaRootS3BotoStorage,個體經營).__的init __(* ARGS,** kwargs)' – niceguydave

1

我有同樣的確切問題,但我想出辦法解決它。

設置我DEFAULT_FILE_STORAGE回到storages.backends.s3boto.S3BotoStorage,這樣一來,當它尋找cache/不會錯過,而且我還可以上傳我的所有文件media/,並python manage.py collectstatic仍然正常工作,因爲我仍然有一組爲StaticRootS3BotoStorage = lambda: S3BotoStorage(location='static')

希望這對你有所幫助,因爲這個問題讓我瘋狂。

+0

謝謝你的幫助!但是當我使用這些設置時,結果是靜態文件在S3上的/ static /文件夾中,但是所有上傳的文件都在根文件夾中,它們不在/ media /中。任何想法? –

+0

對於遲到的回覆,請確保在您的模型中使用'UPLOAD_TO ='media /''。這應該把你上傳的文件放在你想要的地方。 –

+0

是的,我猜你是在做,但我不喜歡,否則它只是打破了Django的工作原理:)無論如何,謝謝! –

0

研究發現,sorl-thumbnail是返回緩存KV圖像0​​使用STATIC_URL(在創建初始縮略圖之後的下一個請求中)。出現MEDIA_URL沒有任何影響。

不是最好的解決方案。添加了一個S3路由規則。

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

我有同樣的問題和薩爾瑪·哈米德的解決方案竟然是對我來說是正確的。

之前我們已經

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

這導致了我們的thumbnail_kvstore表錯了「存儲」的值。此lambda定義不會創建新類,因此類型(StaticRootS3BotoStorage())返回寫入表中的「storages.backends.s3boto.S3BotoStorage」。因爲這些「存儲」值用於稍後存儲實例,以便在顯示時獲取圖像URL,所以導致使用S3BotoStorage()。所以'地點'的理由就失去了。

Salma Hamed的解決方案定義了這些自定義存儲器,類將修復此問題。

謝謝你!

+0

你還記得你學習使用'lambda:S3BotoStorage(location ='static')''以前的解決方案嗎?我想發表評論或更正它。 – Flimm