2012-11-03 5 views
4

Nouveau à Heroku & Amazon S3, alors portez-moi. J'ai téléchargé mon application Django sur Heroku et j'ai eu un problème avec les téléchargements de médias utilisateur. Le modèle est ci-dessous:Télécharger des médias de Heroku à Amazon 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) 

L'attribut poster est celui dans lequel l'image est téléchargée. Je l'ai eu fonctionnait bien localement, et maintenant sur Heroku il y a une erreur. J'ai donc ajouté 'storages.backends.s3boto', comme l'ont dit de nombreux autres articles. (Je ne sais pas si c'est vrai).

Mon fichier Settings.py ressemble à ce moment, une sorte de gâchis:

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

Mon seau est appelé mrt-actifs, et il y a 2 dossiers là statiques (css, js, images et Je ne suis pas trop inquiet pour les fichiers statiques pour l'instant, car j'ai codé en dur les fichiers CSS/JS dans mes fichiers HTML *, mais comment puis-je obtenir mes médias téléchargés par l'utilisateur (images de toute nature) dans mrt-assets/media?

* bien que si quelqu'un voulait aider avec des fichiers STATIC aussi, ce serait génial, mais les médias mis en ligne par l'utilisateur sont plus urgents

EDIT (par commentaire de Yuji):

Avoir essayé un certain nombre d'options, et aucune d'elles ne fonctionnait. Je suis retourné et supprimé beaucoup de changements, et c'est maintenant mes paramètres

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

Pas vraiment sûr de ce qu'il faut faire, besoin de se connecter mon application Heroku à S3 si le téléchargement de médias utilisateur y sont enregistrés.

ont maintenant changé mon seau S3 à ce

+0

Chris, ce qui est l'erreur? J'ai eu des problèmes avec un S3Boto particulier et a dû revenir à une version plus ancienne pour Heroku –

+0

Yuji, éditera la question à remplir sur le statut actuel. Merci d'avance! –

+0

essayé en utilisant [lien] (https://github.com/jamstooks/django-s3-folder-storage) Django s3 dossier de stockage. suivi les instructions dans git, ajouté à INSTALLED_APPS tuple, ajouté à requirements.txt, mais a obtenu le stockage de dossier s3 erreur. –

Répondre

5

L'astuce d'obtenir vos médias pour télécharger dans <bucket>/media et vos actifs statiques dans <bucket>/static est de créer deux différents backends de stockage par défaut pour les deux types d'actifs ou Instanciez explicitement vos champs de modèle avec un objet de stockage en prenant un paramètre location.

instanciation champ modèle avec rangement personnalisé

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) 

Donner S3BotoStorage un location préfixera tous les téléchargements avec son chemin.

Création backends de stockage personnalisé pour les médias et les actifs statiques

C'est presque la même que la définition explicite d'un back-end de stockage avec emplacement, mais nous allons utiliser settings.MEDIA_ROOT et settings.STATIC_ROOT pour appliquer un préfixe de chemin dans le monde.

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

raffinage

Vous pouvez affiner le code ci-dessus pour profiter de Heroku config vars pour le rendre plus portable:

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

Couple les paramètres ci-dessus avec un fichier .env et vous pouvez utiliser les backends de stockage par défaut en local pour le développement et les tests et quand le déploiement sur Heroku vous passera automatiquement à app.storage.S3MediaStorage et app.storage.S3StaticStorage respectivement:

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