3

I am trying to deploy a django app on heroku. I'm currently using the package django-heroku as the standard setup. Under my models some media files that are uploaded using ImageField and I want them to be displayed in my templates. However, although they seem to point to the correct destination they are not being served.

I've looked to similar questions here in SO and looked into the official package git repository looking for examples, however I did not find any example using the same configuration.

settings.py

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static")
] 

MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'

.
.
.

django_heroku.settings(locals())

template

{% extends 'base_site.html' %}
{% load i18n %}
{% block content_title %}{% trans 'Manage Product Detail' %}{% endblock%}
{% block content %}

<div class="card">  
  <div class="carousel-inner" role="listbox">
    {% for figure in product.figures.all %}        
        <div class="item{% if forloop.first %} active{% endif %}">                    
              <img src="{{ figure.image.url }}">
        </div>
    {%endfor%}
  </div>
  <div class="card-body">
    <h5 class="card-title">{{ product.name }}</h5>
    <p class="card-text">{{ product.description }}}
  </div>
  <div class="card-footer">
    <h5 class="card-title">{{ product.name }}</h5>
    <p class="card-text">{{ product.description }}}
  </div>
</div>


{% endblock %}

Although I can confirm that the media folder, subfolder and image exist (at the root of my project) and that the object is present in the template, I'm still presented with the following 404 error:

Not Found: /media/images/Screenshot_from_2018-12-26_21-07-01.png
[04/Jan/2019 14:32:34] "GET /media/images/Screenshot_from_2018-12-26_21-07-01.png HTTP/1.1" 404 2863
André Guerra
  • 486
  • 7
  • 22
  • 1
    possible duplicate https://stackoverflow.com/questions/41474150/using-heroku-for-django-media-files – rollingthedice Jan 04 '19 at 15:01
  • I'd seen that answer but in that case the django-heroku package was not being used and my goal is to have seamless deployment and development. The error I got was in development (I assume the same would happen in production, i'm currently testing) which cannot be attributed to dynos being inactive. – André Guerra Jan 04 '19 at 15:25
  • 1
    You *cannot* store user uploaded files on the Heroku file system. You must use an external store, such as S3. – Daniel Roseman Jan 04 '19 at 20:20
  • Maybe I'm missing something, but I'm testing locally and the file is stored properly in the media folder. – André Guerra Jan 04 '19 at 21:05

3 Answers3

3

The package django-heroku would not provide this functionality out-of-the-box (due to restrictions on heroku side it is impossible to achieve seamless deployment and development of media files). In development one must load the media files through:

urlpatterns = [
    ....
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

In production the static files, as some users referred above must be served from an external source. Here are the tips I'm currently following: https://web.archive.org/web/20170607080235/http://djangobook.com/serving-files-production/

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
André Guerra
  • 486
  • 7
  • 22
2

Follow these steps:

  1. Add Cloudinary Addon to your Heroku app.

  2. Click on cloudinary and install it.

  3. Then click on Cloudinary addon.

  4. From this dashboard you will be able to see your credentials to connect with.

Then go to your project:

  1. IN your terminal type these commands:
pip install django-cloudinary-storage
    
pip install cloudinary
    
pip install Pillow
  1. In your settings.py, add
INSTALLED_APPS = [
       'django.contrib.staticfiles',   
       'cloudinary_storage',
       'cloudinary',
        ]
    
CLOUDINARY_STORAGE = {
             'CLOUD_NAME': 'your_cloud_name',
             'API_KEY': 'your_api_key',
             'API_SECRET': 'your_api_secret'
            }
    
MEDIA_URL = '/media/'  # or any prefix you choose
     
DEFAULT_FILE_STORAGE='cloudinary_storage.storage.MediaCloudinaryStorage'

In models.py:

10.

class TestModel(models.Model):
             name = models.CharField(max_length=100)
             image = models.ImageField(upload_to='images/', 
             blank=True)
  1. Now, in order to put this image into your template, you can just type:
        <img src="{{ test_model_instance.image.url }}" alt="{{ 
        test_model_instance.image.name }}">
  1. requirements.txt:
...
cloudinary==1.17.0
django-cloudinary-storage==0.2.3
char
  • 2,063
  • 3
  • 15
  • 26
Pradip Kachhadiya
  • 2,067
  • 10
  • 28
1

I just want to explain further what others have been saying that Andre failed to understand. When you deploy your project, those media files are not there - they are added when using the application and are available for that period ONLY. When the dyno goes to sleep your application is more or less redeployed (everything is installed again for use) and is exactly the same way you first deployed it - without the media files.

E. A.
  • 11
  • 5