2015-07-11 40 views
19

我已經成功地建立了我的應用程序使用S3存儲所有的靜態和媒體文件。不過,我想上傳到S3(當前操作),但是從我設置的雲端實例提供服務。我曾嘗試將設置調整到雲端網址,但它不起作用。我如何上傳到S3並從Cloudfront提供服務?使用的Cloudfront和Django S3Boto

設置

AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME 

DEFAULT_FILE_STORAGE = 'app.custom_storages.MediaStorage' 
STATICFILES_STORAGE = 'app.custom_storages.StaticStorage' 

STATICFILES_LOCATION = 'static' 
MEDIAFILES_LOCATION = 'media' 

STATIC_URL = "https://s3-eu-west-1.amazonaws.com/app/%s/" % (STATICFILES_LOCATION) 
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIAFILES_LOCATION) 

custom_storages.py

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

class StaticStorage(S3BotoStorage): 
    location = settings.STATICFILES_LOCATION 

class MediaStorage(S3BotoStorage): 
    location = settings.MEDIAFILES_LOCATION 
+2

你有更多的信息,爲什麼它不工作?任何錯誤消息? –

+0

這一點已經在這裏找到答案:http://stackoverflow.com/questions/8688815/django-compressor-how-to-write-to-s3-read-from-cloudfront/8888930#8888930 –

+0

如果它可以幫助任何人,我還必須將'collectstatic'的設置'AWS_DEFAULT_ACL ='''添加到工作中,而不是返回403. – Danra

回答

29

你的代碼是幾乎完全除非您不添加您的CloudFront的域名STATIC_URL/MEDIA_URL和您的自定義儲存。

具體而言,您必須首先安裝依賴

pip install django-storages-redux boto 

添加所需的設置,你的Django設置文件

INSTALLED_APPS = (
    ... 
    'storages', 
    ... 
) 

AWS_STORAGE_BUCKET_NAME = 'mybucketname' 
AWS_CLOUDFRONT_DOMAIN = 'xxxxxxxx.cloudfront.net' 
AWS_ACCESS_KEY_ID = get_secret("AWS_ACCESS_KEY_ID") 
AWS_SECRET_ACCESS_KEY = get_secret("AWS_SECRET_ACCESS_KEY") 

MEDIAFILES_LOCATION = 'media' 
MEDIA_ROOT = '/%s/' % MEDIAFILES_LOCATION 
MEDIA_URL = '//%s/%s/' % (AWS_CLOUDFRONT_DOMAIN, MEDIAFILES_LOCATION) 
DEFAULT_FILE_STORAGE = 'app.custom_storages.MediaStorage' 

STATICFILES_LOCATION = 'static' 
STATIC_ROOT = '/%s/' % STATICFILES_LOCATION 
STATIC_URL = '//%s/%s/' % (AWS_CLOUDFRONT_DOMAIN, STATICFILES_LOCATION) 
STATICFILES_STORAGE = 'app.custom_storages.StaticStorage' 

您的自定義儲存需要一些修改,本作的資源CloudFront的域,而不是S3域:

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

class StaticStorage(S3BotoStorage): 
"""uploads to 'mybucket/static/', serves from 'cloudfront.net/static/'""" 
    location = settings.STATICFILES_LOCATION 

    def __init__(self, *args, **kwargs): 
     kwargs['custom_domain'] = settings.AWS_CLOUDFRONT_DOMAIN 
     super(StaticStorage, self).__init__(*args, **kwargs) 

class MediaStorage(S3BotoStorage): 
"""uploads to 'mybucket/media/', serves from 'cloudfront.net/media/'""" 
    location = settings.MEDIAFILES_LOCATION 

    def __init__(self, *args, **kwargs): 
     kwargs['custom_domain'] = settings.AWS_CLOUDFRONT_DOMAIN 
     super(MediaStorage, self).__init__(*args, **kwargs) 

假設您的存儲桶和雲端域名已正確鏈接,並且用戶的AWS_ACCESS_KEY具有對存儲分區的訪問權限,那麼這就是您所需要的。此外,根據您的使用情況,您可能希望讓每個人都可以讀取您的s3存儲桶項目。

+0

偉大,簡潔的答案。 – Danra

+1

請問爲什麼'MEDIA_URL = '//%S /%S /'代替'MEDIA_URL =的' http://%2 /%S /'優選? – eugene

+1

@eugene通過省略協議說明符(''//而非'的http://'或'的https://')你允許瀏覽器自動選擇適當的協議(http或https)根據含有如何文件被加載。因此,您可以同時提供安全和非安全頁面,並且靜態鏈接保持不變。例如見:http://stackoverflow.com/questions/4831741/can-i-change-all-my-http-links-to-just –

2

我有一個類似的問題,只是將AWS_S3_CUSTOM_DOMAIN設置爲在Django的settings.py爲我工作的Cloudfront網址。您可以檢查代碼here