3 min read

Part 1 - Show Image in Django Admin

Table of Contents

Context

There is no denying the fact that we all love Django and most importantly Django Admin. It provides ready-to-use interactive interface for CRUD operations with models along with tons of customizations and features like filters, pagination, bulk-actions etc.

💡

One of the most powerful parts of Django is the automatic admin interface. It reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site.

Django site

Problem

Wouldn’t it be great if there was a way to display the actual image instead of just the boring link. Well, we are lucky as there are plenty of methods to achieve this.

For ease of understanding and post’s length this will be a 3 part post -

For this tutorial let’s suppose we have a model as below -

class User(AbstractUser):
    # Fields
    profile_pic = models.ImageField(upload_to="upload/images/")

By default, the django admin displays the link for ImageField along with a change button. Here I have an ImageField named “Profile Pic” and it is displayed like this -

Default View

Solution: Use readonly_fields

Django admin provides readonly_fields to allow fields to prevent them from editing. We can create a new method which would return the image tag (<img></img>) with mark_safe which then could be used to display the actual image. Create a method as mentioned below in the User model.

def get_profile_pic_tag(self):
    return mark_safe('<img src="{url}" />'.format(
        url=self.profile_pic.url
    )
)
get_profile_pic_tag.short_description = "Profile Pic"
💡

This method can be created in your ModelAdmin as well. The only difference would be to replace the self parameter with something else like obj or user and use obj.profile_pic.url instead of self.profile_pic.url

Now we can use the above method under the readonly_fields property as below -

@admin.register(models.User)
class UserAdmin(admin.ModelAdmin):
    list_display = ('id', 'first_name', 'last_name', 'email', 'profile_pic',)
    readonly_fields = ('get_profile_pic_tag', )
    ...

And Voila!!! The actual image will be visible as below -

Updated View

In the next part of this tutorial we will understand the cons of using this approach and implement a fix for it.