Visualizing uploaded images in Django Admin

Viewed 5917

Although I've found useful posts on how to correctly display images in the Django-Admin (#1,#2,#3), I've so far not succeeded to follow the advices. As you can see below, the uploaded images are not being properly visualized and an 404 error is being displayed.

The Figure below illustrates the fact that the uploaded images are not being displayed although they've been successfully uploaded on the server: Broken links for uploaded images

When I click with the mouse on the broken link, the following error is displayed on the browser: URL Error

When editing a given object, I was also wondering how to display a thumbnail and not the path of the image: URL to image Below, you can find the configuration that I've been using so far:

settings.py

import os
PROJECT_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..').replace('\\','/')
SITE_ROOT = PROJECT_ROOT

# Path to media files, e.g. images
MEDIA_ROOT = os.path.join(SITE_ROOT, 'media')
MEDIA_URL = '/media/'

urls.py

from django.conf.urls import patterns, include, url
from django.conf.urls.static import static
from django.conf import settings
from . import views

urlpatterns = patterns('',
    # some url configs here ... removed for simplification purposes ;-)
)

if settings.DEBUG is True:
    urlpatterns += patterns('', (r'^media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}) )
    #urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

models.py

class Image(models.Model):
    title = models.CharField(db_column='title', max_length=180, blank=True, null=True, help_text="Title of the image") 
    imagefile = models.ImageField(db_column='imagefile', upload_to='images', null=True, blank=True, help_text="Load an image.")
    #... some other fields here, removed for simplification purposes ;-)

    def image_(self):
        return '<a href="/media/{0}"><img src="/media/{0}"></a>'.format(self.imagefile)
    image_.allow_tags = True

    class Meta:
        managed = False
        db_table = 'image'
    
    def __unicode__(self):
        return u'%s' % (self.title)

admin.py

from django.contrib import admin
from .models import Image

class ImageAdmin(admin.ModelAdmin):
    list_display = ('title', 'description', 'image_', )
    search_fields = ('title', 'description')
    list_per_page = 25

admin.site.register(Image, ImageAdmin)
4 Answers

there is fine line when you use the ImageField and when you use the function image_(self) to make the image visible. See the diagram below: this is the link of the image as my reputation does not allow me to post image. The img1 column represents the imagefile variable you used in models.py.


The images of ImageField are saved in images folder which is the directory your-project/media/images.


Your image_(self) function is pointing to one level deeper when you are using "media/{0}" i.e. it will point to your-project/media//media/images (notice the // here which is coming due to extra / of /{0}). Your functions should be modified as follows:


def image_tag(self):
    return '<a href="{0}"><img src="{0}" width = "120" height = "120"></a>'.format(self.img1.url)
image_tag.allow_tags = True
image_tag.short_description = 'y-Image'

In case you're a Chrome user, try the "Web Server for Chrome" extension, which you can find here: https://stackoverflow.com/a/46480984/14508690

Chrome blocks local resources, so this extension tricks it into 'thinking' it's loading an online resource.

Make sure your src starts with 'http://', as in:

def display_image(self):
    return format_html(
        "<img src='http://127.0.0.1/8887{}'>", 
        self.image_attribute.url
)
Related