Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visualizing uploaded images in Django Admin

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)
like image 511
Tin Avatar asked Mar 23 '16 11:03

Tin


2 Answers

This answer is delayed by at least one year, but, still, if you still have the same problem, you can fix it like this way:

First of all, let's suppose your django project have this architecture and you're running django 2.0:

. django_test
|_ django_test
|  |_ __init__.py
|  |_ settings.py
|  |_ urls.py
|  |_ wsgi.py
|_ media
|  |_ author_headshot
|_ my_app
|  |_ admin.py
|  |_ __init__.py
|  |_ apps.py
|  |_ migrations
|  |_ models.py
|  |_ tests.py
|  |_ urls.py
|  |_ views.py
|_ static
|_ templates

Then, add in your django_test/settings.py :

# static files will be stored in 'static' folder
STATIC_URL = '/static/'
STATICFILES_DIR = [
    BASE_DIR + '/static'
]
# media files will be stored in 'media' folder
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR + '/media'

Then, in django_test/urls.py make sure to add the static path of your MEDIA_URL and MEDIA_ROOT like this example:

from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
    # More paths/urls
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

And finally, in your application model, you can add a unique folder for each ImageField where your media files will be stored like this example:

In my_app/models.py:

from django.db import models
from django.utils.html import format_html

class Author(models.Model):
    # My models ...
    # Here, the media files will be stored in my_project/media/author_headshot
    headshot = models.ImageField(upload_to='author_headshot')

    # If you want to show the media files in the list display in the admin panel:
    def image_tag(self):
        return format_html('<img href="{0}" src="{0}" width="150" height="150" />'.format(self.headshot.url))

    image_tag.allow_tags = True
    image_tag.short_description = 'Image'

Then, in my_app/admin.py :

from django.contrib import admin
from . import models

@admin.register(models.Author)
class AuthorAdmin(admin.ModelAdmin):
    list_display = ('image_tag',)

Finally, your media files will have this kind of urls:

http://example.domain/media/file_path.extension

Screenshots of the django admin panel:

enter image description here

enter image description here

like image 186
Chiheb Nexus Avatar answered Sep 28 '22 09:09

Chiheb Nexus


have you tried something like this:

admin.py

from django.contrib import admin
from .models import Image

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

    def image_display(self, obj):
        return '<a href="/media/{0}"><img src="/media/{0}"></a>'.format(self.imagefile.url)
    image_.allow_tags = True
    image.short_descripition = u'IMAGE'

admin.site.register(Image, ImageAdmin)

That always work for me. Let me know if that helped.

like image 21
jarussi Avatar answered Sep 28 '22 07:09

jarussi