How to Add ImageField in Django Model

How to Add ImageField in Django Model

Introduction

ImageField is one of the field provided by Django model which is used to store an image. As the images in the web page tells about what the contents of the page included, most of the blogger put images in their blog posts. According to statistics, blog posts with images receive 94% more view than those without images. Thus, having at least one image in a post increases the usual traffic in 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 extend 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 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 install Pillow library. To install this library, enter the command in your command prompt(Windows) or terminal(Mac/Linuc) as:

pip install pillow

What is Pillow library?

Pillow is the Python imaging library that allows to perform operations like opening, manipulating, processing, saving to user uploaded images.

Now you can update your  models.py  file with the ImageField. In my case, I will update models.py file of blog app which is one of the app of django project named blog_project that 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 setting 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 as:

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 user.

MEDIA_ROOT is the local path to store media files in 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, Django development server can able to serve the media files during development mode when setting  DEBUG = TRUE  in settings.py file.

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

python manage.py makemigrations blog
python manage.py migrate

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

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

Wait a minute, if you get trouble in 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 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

upload-image-section-django-blog

We added image in the blog post from the admin panel. Now we have to modify 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 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

Conclusion

Hence, we were able to add 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 Django model to upload images and why we need Pillow library for uploading images.

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

Happy Learning:-)

Leave a Reply