Why Not
Why Not

Reputation: 611

Setting MEDIA_URL for Django Heroku App, Amazon S3

I've been attempting to set up a MEDIA_URL for my Heroku app, which is currently serving static files via STATIC_URL from Amazon S3. The static files are working fine, but when I attempt to add a MEDIA_URL in addition to the current STATIC_URL, the pages no longer render at all and the app ceases to work.

The current settings are:

AWS_STORAGE_BUCKET_NAME = 'bucketname'
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
S3_URL = 'http://%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME
STATIC_URL = S3_URL
AWS_ACCESS_KEY_ID = 'KEY'
AWS_SECRET_ACCESS_KEY = 'SECRET_KEY'

When I add:

MEDIA_URL = S3_URL
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'

that causes the issue. Specifically, the MEDIA_URL is problematic as when DEFAULT_FILE_STORAGE is deleted, it still has the same issue. But I'm trying to determine best how to serve user uploaded media through this unsuccessfully.

If anyone has any insight how best to achieve this, it would be most appreciated.

Upvotes: 6

Views: 4045

Answers (2)

alan
alan

Reputation: 3534

This solution works quite well, as described below.

Create a file called s3utils.py in the same directory as settings.py:

from storages.backends.s3boto import S3BotoStorage

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

Then in settings.py:

DEFAULT_FILE_STORAGE = 'myproyect.s3utils.MediaRootS3BotoStorage'
STATICFILES_STORAGE = 'myproyect.s3utils.StaticRootS3BotoStorage'

Upvotes: 4

tiwei
tiwei

Reputation: 728

STATIC_URL and MEDIA_URL can't have the same value, it raises an error.

I had/still have the same problem and couldn't find a clean way to do it. Wait for a better answer, but this is how I solved it (ugly hack):

I'm using django_storages and django_compressor. Since the media files appear in the root of my S3 bucket I can access them through STATIC_URL. In my settings.py:

COMPRESS_URL = "https://s3.amazonaws.com/bucketname/"
STATIC_URL = COMPRESS_URL

In my local dev environment I use MEDIA_URL and for production STATIC_URL. Set an environmental variable that has the value True for your local env and False on Heroku and put it in a context_processor env.

Then you can access the media files in your templates like this:

background-image: url({% if env == 'True' %}{{ MEDIA_URL }}{% else %}{{ STATIC_URL }}{% endif %}{{ course.image }});

It works, but it is ugly. Hopefully somebody found a better solution so I ran refactor my code :)

edit There's a better way: this app lets you create a static and a media folder in S3.

Upvotes: 2

Related Questions