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:
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?
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.
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')
(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
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',)
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')
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 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.
Per @TomRavn comment,
mark_safe works for me.
https://docs.djangoproject.com/en/3.1/ref/utils/#module-django.utils.html
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')
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:
You can also see my answer explaining how to display an uploaded image in "Change" page in Django Admin.
I’m trying to display uploaded images in "Change List" page in Django Admin:
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?
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.
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')
(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
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',)
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')
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 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.
Per @TomRavn comment,
mark_safe works for me.
https://docs.djangoproject.com/en/3.1/ref/utils/#module-django.utils.html
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')
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:
You can also see my answer explaining how to display an uploaded image in "Change" page in Django Admin.