4

Heroku と Amazon S3 は初めてなので、ご容赦ください。Django アプリを Heroku にアップロードしましたが、ユーザー メディアのアップロードに問題がありました。モデルは以下です。

#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)

poster 属性は、画像がアップロードされる属性です。ローカルでは問題なく動作していましたが、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'),)

私のバケットは mrt-assets と呼ばれ、そこには 2 つの静的フォルダー (css、js、images、および media) があります。CSS/JS ファイルを自分のHTML ファイル*ですが、ユーザーがアップロードしたメディア (あらゆる種類の画像) を mrt-assets/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バケットをこれに変更しました

mrt-assets
    static
        css
        js
        images
    media
        (empty)
4

1 に答える 1

5

メディアのアップロード先<bucket>/mediaと静的アセットを取得する秘訣は<bucket>/static、2 つのアセット タイプに対して 2 つの異なるデフォルト ストレージ バックエンドを作成するか、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)

意志を与えるとS3BotoStoragelocationすべてのアップロードにそのパスがプレフィックスとして付けられます。

メディアおよび静的アセット用のカスタム ストレージ バックエンドの作成

これは、場所を指定してストレージ バックエンドを明示的に定義するのとほとんど同じですが、代わりに and を使用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 構成変数 を利用して移植性を高めることができます。

# 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.S3MediaStorageおよびapp.storage.S3StaticStorageそれぞれに切り替わります。

# .env
STATIC_ROOT=static
MEDIA_ROOT=media
DEFAULT_FILE_STORAGE=app.storage.S3MediaStorage
STATICFILES_STORAGE=app.storage.S3StaticStorage
于 2013-01-21T11:06:10.400 に答える