Search code examples
pythonhtmldjangoimagefield

Broken Images on Django


I am getting broken images on django. Below are the relevant information with code, I guess. I am new to django and any information would be greatly appreciated.

name of project/site=imagesite
name of app=gallery

in models.py,

class Photo(models.Model):
    pub_date = timezone.now()
    image = models.ImageField(upload_to='images')

in views.py,

def view_gallery(request):
    photo_list = Photo.objects.all()
    return render(request, 'gallery/view_gallery.html', {'photo_list' : photo_list})

in view_gallery.html,

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Gallery</title>
</head>
<body>

    {% csrf_token %}
    {% for photo in photo_list.all %}

        <img src="{{ photo.image.url }}" width="240">
        <h2> {{ photo.pub_date }} </h2>
        <br>

    {% endfor %}

</body>
</html>

in settings.py,

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

in imagesite/urls.py,

urlpatterns = [
    path('imagesite/', include('gallery.urls')),
    path('admin/', admin.site.urls),
]

in gallery/urls.py,

urlpatterns = [

    path('', views.view_gallery, name='view_gallery'),

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

Solution

  • Your static() urls should be added to the main urls.py file, not to your gallery/urls.py. Now you're prepending them with /imagesite/ so basically you're telling django to create urls /imagesite/media/ rather than /media/.

    Also, just for clarity: This is a url setting that should only be used for development, not for production. So it's better to do like this in your main urls.py:

    from django.conf import settings
    
    urlpatterns = [
        path('imagesite/', include(gallery.urls)),
        ...
    ]
    
    if settings.DEBUG:
        urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    

    Finally, don't assume '/' for paths, as you see you're on Windows, so the path separator is a '\'. Your MEDIA_ROOT setting creates a folder "imagesite/media" rather than a folder "media" inside a folder "imagesite":

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