Upload Multiple Images in Django

There would be many situations where we are in need of uploading multiple images. Django, though doesn’t provide this facility out-of-the-box, we still can do this with a simple modification. So, in this tutorial we’ll learn how to upload multiple images (Can be files too!) at a time in Django.

Project Setup

Let’s make a Django project called multiple_uploads and a Django app called app:

django-admin startproject multiple_uploads
cd multiple_uploads
django-admin startapp app

Setting up our settings.py

We need to do two things (apart from adding our to list of INSTALLED_APPS) in our settings.py file, One is to change the path of template look up directory. Second one is to configure our media folder. Add the below lines to your settings.py file:

import os
....
INSTALLED_APPS = [
    ....
    'app'
]
....
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
....
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
MEDIA_URL = "/media/"

Configuring Our urls

Make sure your multiple_uploads/urls.py looks like this:

from django.contrib import admin
from django.urls import path, include
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('app.urls'))
]

Make a new urls.py file in your app/ directory and add the below lines to it:

from django.urls import path
from . import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
    path('', views.upload, name='upload')
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

The last line is used for serving static files during the development. And remaining everything is self explanatory.

Making models for our images

Add the below lines to your models.py:

from django.db import models
class MultipleImage(models.Model):
    images = models.FileField()

We’re creating a model for storing a single image. So, we’ll store each image in a seperate model object.

Making our views function

Let’s make a view function with name upload in our app/views.py. Add the below lines to it:

from django.shortcuts import render
from .models import MultipleImage
def upload(request):
    if request.method == "POST":
        images = request.FILES.getlist('images')
        for image in images:
            MultipleImage.objects.create(images=image)
    images = MultipleImage.objects.all()
    return render(request, 'index.html', {'images': images})

Everything is familier to us, but only the line images = request.FILES.getlist(‘images’) might be nwe to you, this line gets a list of selected images from our template. We’ll iterate through this list of images and store each image in the model. Then we’ll retrieve all the objects and send it to the template for rendering.

Creating our templates

Make a folder called templates in your project’s root directory and make an index.html file in it. Add the below lines to that file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mutliple Upload</title>
    <style>
        img {
            height: 200px;
            width: 200px;
        }
    </style>
</head>
<body>
    <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="file" name="images" multiple>
        <button>Upload</button>
    </form>
    <hr>
    {% for img in images %}
    <img src="{{img.images.url}}" alt="Image">
    {% endfor %}
</body>
</html>

Pay attention to the enctype = “multipart/form-data”, this is important!. Since HTML <input/> tag only supports a single selection, we need to add an additional attribute called multiple. This enables us to select multiple images. And everything else is understandable, we’re iterating and displaying through the list of image models we got from our views.py.

We’re done!

Finally we just need do some basic migrations:

python manage.py makemigrations
python manage.py migrate
python manage.py runserver

Now, open 127.0.0.1:8000 in your favourite browser. You can upload multiple images or files with Django

Get the code from my GitHub repo: https://github.com/Chandu-4444/Multiple-image-uploads