djangoherokustaticmedia

How to deploy media files in django-heroku?


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

Solution

  • 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