Salut à tous. Je suis débutant sur heroku.
J'ai crée une application django que j'ai déployé sur heroku.
je rencontre un problème. En effet, les images statiques s'affichent bel et bien, mais pas les images dynamiques.
Dans mon application, il y a une template qui présente des livres ainsi que leur auteur. Les informations (textes) s'affichent bien mais pas l'image du livre et celle de l'auteur. En inspectant le code et en plaçant le curseur sur la valeur de l'attribut "src", il est marqué: Could not load the image.
Pouvez-vous m'aidez?

J'utilise entre autres:
- Django 2.0
- Python 3.6.3
- pipenv

Voici le codes des fichiers concernés:

- Settings:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
"""
Django settings for dizikland project.
 
Generated by 'django-admin startproject' using Django 2.0.4.
 
For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/
 
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""
 
import os
import django_heroku
 
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
 
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/
 
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'm5xi5mk58c*q6jdnu-v2)*&=gf$)41s08sojsy6h$g+ts%-)b)'
 
# SECURITY WARNING: don't run with debug turned on in production!
if os.environ.get("ENV") == "PRODUCTION":
    DEBUG = False
else:
    DEBUG = True
 
ALLOWED_HOSTS = ['localost', 'dizikland.herokuapp.com']
 
 
# Application definition
 
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.humanize',
    'contact',
    'disco',
    'ckeditor',
]
 
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
 
ROOT_URLCONF = 'dizikland.urls'
 
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
 
WSGI_APPLICATION = 'dizikland.wsgi.application'
 
 
# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases
 
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'dizikland',
        'USER': 'django',
        'PASSWORD': 'django',
        'HOST': 'localhost',
        'PORT': '5432'
    }
}
 
 
# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
 
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]
 
 
# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/
 
LANGUAGE_CODE = 'en-us'
 
TIME_ZONE = 'UTC'
 
USE_I18N = True
 
USE_L10N = True
 
USE_TZ = True
 
 
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
 
STATIC_URL = '/static/'
 
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
 
# Config for pictures management
 
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
 
django_heroku.settings(locals())
 
# Config for rich textarea (ckeditor using)
CKEDITOR_CONFIGS = {
    'default': {
        'skin': 'moono',
        'skin': 'office2013',
        'toolbar_Basic': [
            ['Source', '-', 'Bold', 'Italic']
        ],
    },
    'awesome_ckeditor': {
        'toolbar': 'Custom',
        'width': 500,
        'toolbar_Custom': [
            ['Bold', 'Italic', 'Underline'],
            ['NumberedList', 'BulletedList', '-', 'Outdent', 'indent', '-',
             'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
            ['Link', 'Unlink'],
            ['RemoveFormat', 'Source']
        ]
    }
}

- urls:py (fichier urls global)

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
"""dizikland URL Configuration
 
The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path, include
from django.views.generic import TemplateView
from django.conf.urls.static import static
from django.conf import settings
 
urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^$', TemplateView.as_view(template_name='home.html'),
            name='home'),
    re_path(r'^team/$', TemplateView.as_view(template_name='team.html'),
            name='team'),
    re_path(r'^contact/', include('contact.urls')),
    re_path(r'^disco/', include('disco.urls')),
]
- Template affichant la liste des livres et leur auteur

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!-- Books list -->
<div class="pmd-card pmd-card-default pmd-z-depth item_card">
    <!-- Card header -->
    <div class="pmd-card-title">
        <div class="media-left">
            <a href="{% url 'author' slug=book.author.slug %}" data-toggle="tooltip" data-placement="top" title="know more about author"
                class="avatar-list-img pmd-tooltip">
                <img width="40" height="40" src="{{ book.author.avatar.url }}">
            </a>
        </div>
        <div class="media-body media-middle">
            <h3 class="pmd-card-title-text">{{ book.author.name }}</h3>
        </div>
    </div>
 
    <!-- Card media -->
    <div class="pmd-card-media">
        <a href="{% url 'book' slug=book.slug %}">
            <img width="1184" class="img-responsive item_card pmd-tooltip" data-toggle="tooltip" data-placement="top" title="{{ book.title }}"
                src="{{ book.avatar.url }}">
        </a>
    </div>
 
    <!-- Card body -->
    <div class="pmd-card-body">
        <p class="text-center pmd-card-title-text">
            <a href="{% url 'book' slug=book.slug %}">
                {{ book.title }}
                <br> ( {{ book.parution|date:"Y" }} )
            </a>
        </p>
 
        {{ book.summary|truncatewords:30|safe }}
    </div>
 
    <!-- Card actions -->
    <div class="pmd-card-actions text-right">
        <a href="{% url 'book' slug=book.slug %}" type="button" class="btn btn-sm pmd-btn-fab pmd-btn-flat pmd-ripple-effect btn-primary">
            <i class="material-icons pmd-sm">add</i>
        </a>
        <a href="{{ book.avatar.url }}" name="avatar.jpeg" download="{{ book.slug }}.jpeg" type="button" class="btn btn-sm pmd-btn-fab pmd-btn-flat pmd-ripple-effect btn-primary">
            <i class="material-icons pmd-sm">file_download</i>
        </a>
    </div>
</div>
- models.py (model des livres et son model parent. J'ai utilisé l'héritage)

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
 
class Item(models.Model):
    """Item model
 
    It's an abstract model and represent:
    - book
    - album
    - song
    - movie
 
    Attributes:
        title {str}     -- title
        parution {date} -- parution date
        avatar {img}    -- item avatar, picture
 
    """
 
    title = models.CharField(max_length=80, unique=True)
    parution = models.DateField()
    avatar = models.ImageField(upload_to='item_avatar/')
    slug = models.SlugField()
 
    class Meta:
        """ Declare this model as abstract """
 
        abstract = True
 
 
class Book(Item):
    """Book model
 
    It's represent a book, and herits from Item
 
    Attributes:
        category {str}  -- category, kind of book
        summary {text}  -- book summary
        author {id}     -- book author (author_id)
        home {id}       -- book home edition (home_id)
 
    Returns:
        [str] -- book author and book title
    """
 
    MANGAS = 'Mangas'
    NOVELETTE = 'Novelette'
    THEATER = 'Theater'
    NOVEL = 'Novel'
    POEM = 'Poem'
    CHRONIC = 'Chronic'
 
    BOOK_CATEGORY_CHOICES = {
        (MANGAS, 'Mangas'),
        (NOVELETTE, 'Novelette'),
        (THEATER, 'Theater'),
        (NOVEL, 'Novel'),
        (POEM, 'Poem'),
        (CHRONIC, 'Chronic')
    }
 
    category = models.CharField(max_length=10, default=MANGAS,
                                choices=BOOK_CATEGORY_CHOICES)
    summary = RichTextField(config_name='awesome_ckeditor',)
    page_number = models.PositiveIntegerField(blank=True, null=True,
                                              verbose_name="Book pages")
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    home = models.ForeignKey(EditionHome, default=1,
                             on_delete=models.SET_DEFAULT)
 
    def __str__(self):
        return "{}: {}".format(self.author.name, self.title)
 
    class Meta:
        verbose_name = "Book section"
        verbose_name_plural = "Books section"