Reputation: 1234
I am trying to deploy my django app on heroku. All the static files are served by whitenoise
and are migrated successfully. But how do I get my media files that are uploaded using ImageField
to display during production.
my settings.py
STATIC_URL = '/static/'
STATIC_ROOT = 'C:/Users/Sak/mpro/feat/static/'
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
wsgi.py
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mpro.settings")
application = get_wsgi_application()
try:
from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise
application = get_wsgi_application()
application = DjangoWhiteNoise(application)
from dj_static import Cling
application = Cling(get_wsgi_application())
except:
pass
urls.py
urlpatterns = [
url(r'^', include('feat.urls', namespace="feat")),
url(r'^admin/', include(admin.site.urls)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
All my media files are uploaded to base_dir/media/media
and when whitenoise
collects static files it only collects files at STATIC_ROOT
, so how do I get my media files deployed. When I run heroku run ls
I can see the folder media.
Upvotes: 20
Views: 6099
Reputation: 7083
So, first of all it's important to realise that if you have a bunch of files that are part of your project (including things like images and such) and are deployed along with it, they are more likely to be static files than media files in Django parlance.
Media files in Django are for runtime uploaded files. They will generally be stored with a corresponding db entry such as models.ImageField(upload_to='/photos')
but that isn't necessarily so.
Your media setup is wrong for Heroku, as you shouldn't be writing to a directory on the server anyway (this is what you are telling Django to do with MEDIA_ROOT = os.path.join(BASE_DIR, "media")
.
Most commonly you would instead use an S3 bucket for media on Heroku. This is a fairly comprehensive explanation of that. You can probably skip the bit about CORS and go for open permissions on the bucket (depending on your use case). The important bits are:
# settings.py
# Tell django what URL to server your media from
MEDIA_URL = "https://%s/" % AWS_S3_CUSTOM_DOMAIN
# Tell Django to use the boto storage backend to save media files.
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
If you want to use S3 for static AND media storage, the link explains that too.
You might want to look at this repo for a pretty comprehensive run-down of the AWS settings and what they do, plus a nicely wrapped package to do some of it for you.
More generally I found Django Herokuify exceptionally useful for all the boilerplate on Heroku.
Upvotes: 11