How to Add ImageField in Django Model | Python Sansar

Introduction

ImageField is one of the fields provided by the Django model which is used to store an image. As the images on the web page tell about what the contents of the page included, most bloggers put images in their blog posts. According to statistics, blog posts with images receive 94% more views than those without images. Thus, having at least one image in a post increases the usual traffic on our website.

ImageField in the model inherits most of the features of FileField and also validates whether the uploaded image is valid or not. In extension, ImageField contains extra attributes height and width which are not available in FileField.

ImageField(upload_to=None, height_field=None,\
           width_field=None, max_length=100, **options)

Here in this article, we are going to enhance the blog application by the feature of the image that we discussed in the post: How to Create a Blog Application Using Django

 

Implementation

Before updating the model with the ImageField, we need to install the Pillow library. To install this library, enter the command in your command prompt(Windows) or terminal(Mac/Linux) as:

pip install pillow

What is Pillow library?

Pillow is the Python imaging library that allows performing operations like opening, manipulating, processing, and saving user-uploaded images.

 

Now you can update your models.py file with the ImageField. In my case, I will update the models.py file of the blog app which is one of the apps of the Django project named blog_project that was created in the previous article.

# blog/models.py
from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.contrib.auth.models import User


class Post(models.Model):
    title = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(max_length=250,
                            unique=True)
    author = models.ForeignKey(User,
                               on_delete=models.CASCADE,
                               related_name='blog_posts')
    # adding the ImageField
    image = models.ImageField(blank=True, upload_to='blog_images')
    body = models.TextField()
    publish = models.DateTimeField(default=timezone.now)

    class Meta:
        ordering = ('-publish',)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('blog:blog_detail', args=[self.slug])

After that, you have to configure  MEDIA_ROOT and MEDIA_URL settings by giving the path where you want to store media files locally in your system.

 

Go to the  settings.py  file of your project, and add the following lines of code:

MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / 'media'

# for django version < 3.1
# import os at the top
# MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

What are MEDIA_URL and MEDIA_ROOT?

MEDIA_URL is the base URL used to serve the media file uploaded by the user.

MEDIA_ROOT is the local path to store media files on your computer.

 

Now you have to edit the main  urls.py  file of your project as:

from django.urls import path, include
from django.contrib import admin
# import settings and static first
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls', namespace='blog')),
]

# add this lines
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

By doing this, the Django development server can able to serve the media files during development mode when setting  DEBUG = TRUE  in the settings.py file.

Then you have to migrate the changes to your database using the command:

python manage.py makemigrations blog
python manage.py migrate

The first command creates new migration records and the second command migrate those record to the database.

Note: You have to mention your app name where the models.py file actually resides. In my case, my app name is ‘blog’ inside the django-blog directory.

Wait a minute, if you get trouble running migration files and see the error messages as like:

...........
...........

ERRORS:
blog.Post.image: (fields.E210) Cannot use ImageField because Pillow is not installed.
        HINT: Get Pillow at https://pypi.org/project/Pillow/ or run command "python -m pip install Pillow".

Then you should install the pillow library first using pip as mentioned above. So first install the library then only try to migrate records to the database.

 

Now let’s add images to the new blog post by running the development server with the command:

python manage.py runserver

 

After that login to the administration site of your project by opening the URL in your browser:

http://127.0.0.1:8000/admin

add-new-post-django-blog

add-new-post-django-blog

upload-image-section-django-blog

upload-image-section-django-blog

We added an image in the blog post from the admin panel. Now we have to modify the template file so that it can be able to show our uploaded images.

For that I am going to update  blog_detail.html  inside the templates directory file with the code:

<!--templates/blog/blog_detail.html-->

{% extends 'base.html' %}

{% block container %}
<div class="row">
    <div class="card">
        <img src="{{ post.image.url }}" class="card-img-top img-fluid" alt="{{ post.title }}">
        <div class="card-body">
            <h1 class="card-title">{{ post.title }}</h1>
            <h5 class="card-title">Published: {{ post.publish }} by <span class="text-primary">{{ post.author }}</h5>
            <p class="card-text">{{ post.body }}</p>
        </div>
    </div>
</div>

{% endblock %}

Here inside the <img> tag, we have to provide the ‘src’ attribute with the value of the image URL in order to render that image in the browser.

<img src="{{ post.image.url }}" 
             class="card-img-top img-fluid" alt="{{ post.title }}">

imageview-django-model-example

imageview-django-model-example

Conclusion

Hence, we were able to add an image field in our Django model and show that uploaded image in our templates.

We learn how images are stored in the system and about the ImageField is the input field provided by the Django model to upload images and why we need the Pillow library for uploading images.

What’s your opinion about the article? Leave your comments below.

Happy Learning:-)