2012-11-03 28 views
4

Heroku新手&亞馬遜S3,請耐心等待。將我的Django應用上傳到Heroku,並且遇到用戶媒體上傳的問題。型號如下:從Heroku上傳媒體到亞馬遜S3

#models.py 
class Movie(models.Model): 
    title   = models.CharField(max_length = 500) 
    poster   = models.ImageField(upload_to = 'storages.backends.s3boto') 
    pub_date  = models.DateTimeField(auto_now_add = True) 
    author   = models.ForeignKey(User) 

海報屬性是圖片上傳的地方。我在本地運行良好,現在在Heroku上出現錯誤。所以我添加了'storages.backends.s3boto',就像其他許多帖子告訴我的一樣。 (不知道是否正確)。

我Settings.py文件看起來像這樣,現在,那種亂七八糟:

#settings.py 
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) 
PROJECT_DIR = os.path.join(PROJECT_ROOT, '../qanda') 

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage' 
STATICFILES_STORAGE  = 'storages.backends.s3boto.S3BotoStorage' 

AWS_ACCESS_KEY_ID   = '****************' 
AWS_SECRET_ACCESS_KEY  = '************' 
AWS_STORAGE_BUCKET_NAME = 'mrt-assets' 
AWS_PRELOAD_METADATA  = True 

MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'qanda/media/movie_posters/) 
MEDIA_URL = '/media' 
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles') 
STATIC_URL = 'https://mrt-assets.s3.amazonaws.com/static/' 
STATICFILES_DIRS = (os.path.join(PROJECT_DIR, 'static'),) 

我鬥被稱爲地鐵資產,並有在那裏靜(CSS,JS,圖片2個文件夾和我現在不太擔心靜態文件,因爲我已經將CSS/JS文件硬編碼到我的HTML文件*中,但是如何將我的用戶上傳的媒體(任何類型的圖像)轉換爲mrt資產/ media?

*雖然如果有人想幫助使用STATIC文件,那太棒了,但是用戶上傳的媒體更加緊急

編輯(根據Yuji的評論):

已經嘗試了一些選項,並沒有一個工作。我已經走了回來,並刪除了很多的變化,這就是我現在的設置

#settings.py 
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__)) 
MEDIA_ROOT = 'http://s3.amazonaws.com/mrt-assets/media/' 
MEDIA_URL = '/media/' 
STATIC_ROOT = 'http://s3.amazonaws.com/mrt-assets/static/' 
STATIC_URL = '/static/' 
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/' 
TEMPLATE_DIRS = (os.path.join(PROJECT_ROOT, "templates"),) 

#models.py 
#same as before, but now have changed the poster directory 
poster = models.ImageField(). 

不能確定做什麼,需要我的Heroku應用程序連接到S3所以用戶上傳的媒體被保存在那裏。

現在已經改變了我S3桶這一

+0

克里斯,有什麼錯誤?我有一個特定的S3Boto問題,不得不恢復到Heroku的舊版本 –

+0

Yuji,將編輯問題以填寫當前狀態。提前致謝! –

+0

嘗試使用[鏈接](https://github.com/jamstooks/django-s3-folder-storage)Django s3文件夾存儲。遵循git中的指令,添加到INSTALLED_APPS元組中,添加到requirements.txt中,但得到錯誤s3文件夾存儲。 –

回答

5

得到媒體的伎倆上傳到<bucket>/media和你的靜態資產注入<bucket>/static是兩個資產類型或創建兩個不同的默認存​​儲後端使用參數location的存儲對象顯式實例化模型字段。

實例化的模型字段自定義存儲

from storages.backends.s3boto import S3BotoStorage 

class Movie(models.Model): 
    title = models.CharField(max_length=500) 
    poster = models.ImageField(storage=S3BotoStorage(location='media')) 
    pub_date = models.DateTimeField(auto_now_add=True) 
    author = models.ForeignKey(User) 

給予S3BotoStorage一個location將前綴的所有上傳與它的路徑。

創建的媒體和靜態資產

定製的存儲後端這幾乎是一樣的明確定義與 位置的存儲後端,而是我們將使用settings.MEDIA_ROOTsettings.STATIC_ROOT在全球範圍內適用的路徑前綴。

# settings.py 
STATIC_ROOT = '/static/' 
MEDIA_ROOT = '/media/' 

DEFAULT_FILE_STORAGE = 'app.storage.S3MediaStorage' 
STATICFILES_STORAGE = 'app.storage.S3StaticStorage' 


# app/storage.py 
from django.conf import settings 
from storages.backends.s3boto import S3BotoStorage 

class S3MediaStorage(S3BotoStorage): 
    def __init__(self, **kwargs): 
     kwargs['location'] = kwargs.get('location', 
      settings.MEDIA_ROOT.replace('/', '')) 
     super(S3MediaStorage, self).__init__(**kwargs) 

class S3StaticStorage(S3BotoStorage): 
    def __init__(self, **kwargs): 
     kwargs['location'] = kwargs.get('location', 
      settings.STATIC_ROOT.replace('/', '')) 
     super(S3StaticStorage, self).__init__(**kwargs) 

提煉它

可以提煉上面的代碼,以利用 Heroku config vars ,使其更加便於攜帶:

# settings.py 
import os 
STATIC_ROOT = os.environ.get('STATIC_ROOT', 
    os.path.join(os.path.dirname(__file__), 'static')) 

MEDIA_ROOT = os.environ.get('MEDIA_ROOT', 
    os.path.join(os.path.dirname(__file__), 'media')) 

DEFAULT_FILE_STORAGE = os.environ.get('DEFAULT_FILE_STORAGE', 
    'django.core.files.storage.FileSystemStorage') 

STATICFILES_STORAGE = os.environ.get('STATICFILES_STORAGE', 
    'django.contrib.staticfiles.storage.StaticFilesStorage') 

夫婦上面設置有.env文件,您可以在本地使用 默認存儲後端進行開發和測試,並且在Heroku上部署 時,您將自動切換分別 app.storage.S3MediaStorageapp.storage.S3StaticStorage

# .env 
STATIC_ROOT=static 
MEDIA_ROOT=media 
DEFAULT_FILE_STORAGE=app.storage.S3MediaStorage 
STATICFILES_STORAGE=app.storage.S3StaticStorage