How to display uploaded images in "Change List" page in Django Admin?

Question:

I’m trying to display uploaded images in "Change List" page in Django Admin:

enter image description here

This is my code below:

# "models.py"

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=50)
    price = models.DecimalField(decimal_places=2, max_digits=5)
    image = models.ImageField()
        
    def __str__(self):
        return self.name
# "admin.py"

from django.contrib import admin
from .models import Product

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ('name', 'price', 'image',)

So, how can I display uploaded images in "Change List" page in Django Admin?

Asked By: Oleg Tarasenko

||

Answers:

You can overwrite django admin view for your model. See http://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-admin-templates for more details.

In a brief you need to create a template: templates/admin/your_app/article/change_form.html
And there add html to display the image.

Answered By: Piotr Czapla

You can create a model instance method with another name, allow HTML tags for its output and add this method as a list field. Here is an example:

First add a new method returning the HTML for the image inclusion:

class Article(models.Model):
    ...
    def admin_image(self):
        return '<img src="%s"/>' % self.img
    admin_image.allow_tags = True

Then add this method to the list:

class ArticleAdmin(admin.ModelAdmin):    
    ...
    list_display = ('url', 'title', 'admin_image')
Answered By: Michael

(I’m using Django 1.5)
In addition to following the steps in the accepted answer, I ALSO had to mark the image tag as being “safe”

To do this, wrap the return value with the mark_safe method of django.utils.safestring package.

code example: https://stackoverflow.com/a/14075441/1063031

django docs: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#filters-and-auto-escaping

Answered By: pumababi
def image_tag(self, obj):
    return u'<img src="%s" />' % obj.image

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

and in your admin.py add:

   readonly_fields = ('image_tag',)
Answered By: Avinash Garg

you can also add the image directly in admin

class ProductAdmin(admin.ModelAdmin):
        
     def admin_image(self, obj):                       
        return '<img src="%s"/>' % obj.img
     admin_image.allow_tags = True

     list_display = ('name', 'price', 'image', 'admin_image')
Answered By: Javed

UPDATE 2020

Because this answer is getting a lot of traction recently, I decided to make small edit.
According to django doc it is recommended to use function format_html.
As @chem1st suggested, if you need it only for admin, everything can be made in admin.py only.

My models.py

from django.db import models

class Product(models.Model):
    title = models.CharField(max_length=120)
    description = models.TextField()
    price = models.DecimalField(decimal_places = 2, max_digits = 20, default = 00.00)
    image = models.ImageField(upload_to=change_image_name, null=True, blank=True)

    def __str__(self):
        return self.title

My admin.py

from django.contrib import admin
from django.utils.html import format_html

from .models import Product

class ProductAdmin(admin.ModelAdmin):
    list_display = ('title', 'description', 'price', 'image_tag')

    def image_tag(self,obj):
        return format_html('<img src="{0}" style="width: 45px; height:45px;" />'.format(obj.image.url))

admin.site.register(Product, ProductAdmin)

UPDATE django 2.0.6

I was solving this problem in latest django 2.0.6. I wanted have an image thumbnail in a list view in the django-admin.

Picture below is my default admin listview.

This is my default admin view

This is my models.py:

from django.db import models
from django.utils.safestring import mark_safe

# Create your models here.

class Product(models.Model):
    title = models.CharField(max_length=120)
    description = models.TextField()
    price = models.DecimalField(decimal_places = 2, max_digits = 20, default = 00.00)
    image = models.ImageField(upload_to=change_image_name, null=True, blank=True)

    def image_tag(self):
        if self.image:
            return mark_safe('<img src="%s" style="width: 45px; height:45px;" />' % self.image.url)
        else:
            return 'No Image Found'
    image_tag.short_description = 'Image'
    

    def __str__(self):
        return self.title

Please notice I had to use mark_safe() on the image string, otherwise you
will get escaped html code instead of a thumbnail in the django-admin

Finally, this is my admin.py

from django.contrib import admin

from .models import Product
# Register your models here.
class ProductAdmin(admin.ModelAdmin):
    list_display = ('title', 'description', 'price', 'image_tag')

admin.site.register(Product, ProductAdmin)

Here we have to register the ProductAdmin class too, I didn’t know that
and it didn’t work.

This is result:
enter image description here

Answered By: TomRavn
Answered By: Edgar Ronda
models.py
from django.utils.html import format_html


class Test(models.Model):
    title                   = ...
    photo                   = ...
    
    def image(self):
        return format_html('<img src="%s"/>' % self.photo.url)
admin.py
@admin.register(models.Test)
class testAdmin(admin.ModelAdmin):
    list_display =    ('title','image')
Answered By: Darwin

You need to create image_tag column with image_tag() then assign it to list_display as shown below:

# "admin.py"

from django.contrib import admin
from .models import Product
from django.utils.html import format_html

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):         # Here
    list_display = ('name', 'price', 'image', 'image_tag')

    def image_tag(self, obj): # Here
        return format_html(
            f'''<a href="{obj.image.url}" target="_blank">
                  <img 
                    src="{obj.image.url}" alt="{obj.image}" 
                    width="50" height="50"
                    style="object-fit: cover;"
                  />
                </a>''')

Then, you can display uploaded images in "Change List" page in Django Admin as shown below:

enter image description here

You can also see my answer explaining how to display an uploaded image in "Change" page in Django Admin.

Answered By: Kai – Kazuya Ito