Lesson 51 of 60 – Django Image Upload
85%

Django Image Upload

Image upload allows users to upload images such as profile photos, student photographs, product images, certificates, and other pictures to a Django application.

Django provides ImageField for working with images. Image uploads use many of the same concepts as normal file uploads, including MEDIA_ROOT, MEDIA_URL, request.FILES, and multipart forms.

Note: Django's ImageField uses the Pillow library to validate and process image files.

1. What is Image Upload?

Image upload is the process of sending an image from a user's device to a web application.

Common examples include:

  • Profile photos.
  • Student photographs.
  • Product images.
  • Blog images.
  • Certificate images.
  • Gallery pictures.

2. ImageField

Django provides ImageField for storing references to uploaded images.

from django.db import models

class Student(models.Model):

    name = models.CharField(
        max_length=100
    )

    photo = models.ImageField(
        upload_to="students/"
    )

The image is stored through the configured file-storage system.

3. ImageField vs FileField

Field Purpose
FileField General file uploads.
ImageField Image uploads with image validation.

Use ImageField when the uploaded content is expected to be an image.

4. Installing Pillow

Django's ImageField requires Pillow.

Install Pillow using:

python -m pip install Pillow

You can verify the installation using:

python -m pip show Pillow

5. Creating an Image Model

from django.db import models

class Student(models.Model):

    name = models.CharField(
        max_length=100
    )

    photo = models.ImageField(
        upload_to="students/"
    )

    created_at = models.DateTimeField(
        auto_now_add=True
    )

The photo field stores the reference to the uploaded image.

6. upload_to for Images

The upload_to option specifies where uploaded images should be stored relative to the configured media storage.

photo = models.ImageField(
    upload_to="students/"
)

Another example:

image = models.ImageField(
    upload_to="products/"
)

7. MEDIA_ROOT

MEDIA_ROOT defines the filesystem location where uploaded media files are stored.

MEDIA_ROOT = BASE_DIR / "media"

For example, student images can be stored under:

media/students/

8. MEDIA_URL

MEDIA_URL defines the URL prefix used to access uploaded media.

MEDIA_URL = "/media/"

Together, MEDIA_ROOT and MEDIA_URL are commonly used when handling uploaded images.

9. Creating the Media Directory

Create a media directory in the project when using local filesystem storage during development.

project/
│
├── manage.py
├── media/
│
├── students/
│
└── project/

Django will organize uploaded images inside this directory according to the upload_to value.

10. Image Upload Form

The HTML form must use multipart/form-data.

<form
    method="post"
    enctype="multipart/form-data"
>

    {% csrf_token %}

    <input
        type="text"
        name="name"
        placeholder="Student Name"
    >

    <input
        type="file"
        name="photo"
    >

    <button type="submit">
        Upload Photo
    </button>

</form>

11. Accepting Image Files in HTML

The HTML file input can use the accept attribute to guide the user toward selecting images.

<input
    type="file"
    name="photo"
    accept="image/*"
>

This improves the browser interface, but server-side validation is still required.

12. request.FILES

Uploaded images are available through request.FILES.

photo = request.FILES.get(
    "photo"
)

The key must match the name of the file input.

13. Basic Image Upload View

from django.shortcuts import render
from .models import Student

def upload_photo(request):

    if request.method == "POST":

        name = request.POST.get(
            "name"
        )

        photo = request.FILES.get(
            "photo"
        )

        Student.objects.create(
            name=name,
            photo=photo
        )

    return render(
        request,
        "upload_photo.html"
    )

14. Checking Whether an Image Was Selected

Check whether the user actually selected an image.

photo = request.FILES.get(
    "photo"
)

if photo:

    print("Image selected")

else:

    print("No image selected")

15. Image Name

The uploaded file object provides the original filename.

photo.name

For example:

student_photo.jpg

Do not blindly trust the original filename when performing filesystem operations.

16. Image Size

The uploaded image's size can be checked using the size attribute.

photo.size

For example, to restrict an image to 5 MB:

if photo.size > 5 * 1024 * 1024:

    print("Image is too large")

17. Image Validation

An application should validate uploaded images before storing them.

Common validation checks include:

  • File size.
  • Image format.
  • Image dimensions.
  • Whether the uploaded content is actually an image.

18. Checking Image Extension

You can inspect the filename extension as one part of validation.

import os

extension = os.path.splitext(
    photo.name
)[1].lower()

allowed = [
    ".jpg",
    ".jpeg",
    ".png",
    ".webp"
]

if extension not in allowed:

    print("Invalid image extension")

Extension checking alone is not sufficient to prove that a file is a valid image.

19. Image Dimensions

Pillow can be used to inspect image dimensions when additional validation is required.

from PIL import Image

image = Image.open(photo)

width, height = image.size

print(width)
print(height)

For example, an application may require profile photos to have minimum dimensions.

20. Using ModelForm for Image Upload

A ModelForm can make image-upload handling easier.

from django import forms
from .models import Student

class StudentForm(forms.ModelForm):

    class Meta:

        model = Student

        fields = [
            "name",
            "photo"
        ]

21. ModelForm Image Upload View

from django.shortcuts import render, redirect
from .forms import StudentForm

def upload_photo(request):

    if request.method == "POST":

        form = StudentForm(
            request.POST,
            request.FILES
        )

        if form.is_valid():

            form.save()

            return redirect(
                "students"
            )

    else:

        form = StudentForm()

    return render(
        request,
        "upload_photo.html",
        {
            "form": form
        }
    )

Notice that both request.POST and request.FILES are passed to the ModelForm.

22. Image Upload Template

<form
    method="post"
    enctype="multipart/form-data"
>

    {% csrf_token %}

    {{ form.as_p }}

    <button type="submit">
        Upload Photo
    </button>

</form>

The multipart encoding is required for the image to reach request.FILES.

23. Displaying an Uploaded Image

The url property of an ImageField can be used to display an uploaded image.

<img
    src="{{ student.photo.url }}"
    alt="{{ student.name }}"
>

The image URL is generated according to the configured storage.

24. Checking if an Image Exists

Before accessing photo.url, check that an image exists.

{% if student.photo %}

    <img
        src="{{ student.photo.url }}"
        alt="{{ student.name }}"
    >

{% else %}

    <p>
        No photo available.
    </p>

{% endif %}

25. Serving Media During Development

During development, Django can serve media files through the development server configuration.

In the project's main urls.py:

from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [

    # Your URL patterns

]

urlpatterns += static(
    settings.MEDIA_URL,
    document_root=settings.MEDIA_ROOT
)

This is intended for development. Production deployments should use an appropriate web server or storage service for media files.

26. Common Image Upload Mistakes

  • Forgetting to install Pillow.
  • Forgetting ImageField configuration.
  • Forgetting enctype="multipart/form-data".
  • Forgetting to pass request.FILES.
  • Forgetting MEDIA_ROOT.
  • Forgetting MEDIA_URL.
  • Not running migrations.
  • Not checking whether an image exists before using .url.
  • Not validating image size.
  • Trusting only the filename extension for image validation.

27. Image Upload Security

  • Validate uploaded content on the server.
  • Restrict allowed image formats when appropriate.
  • Limit image file size.
  • Consider image dimensions.
  • Do not trust the original filename.
  • Use appropriate media storage permissions.
  • Use HTTPS in production.
  • Serve uploaded media carefully.

28. Complete Image Upload Workflow

User Selects Image
        ↓
Multipart Form
        ↓
POST Request
        ↓
request.FILES
        ↓
Image Validation
        ↓
ImageField / ModelForm
        ↓
Save Image
        ↓
MEDIA_ROOT
        ↓
Store File Reference
        ↓
Display Image

29. Complete Image Upload Example

models.py

from django.db import models

class Student(models.Model):

    name = models.CharField(
        max_length=100
    )

    photo = models.ImageField(
        upload_to="students/"
    )

forms.py

from django import forms
from .models import Student

class StudentForm(forms.ModelForm):

    class Meta:

        model = Student

        fields = [
            "name",
            "photo"
        ]

views.py

from django.shortcuts import render, redirect
from .forms import StudentForm

def upload_photo(request):

    if request.method == "POST":

        form = StudentForm(
            request.POST,
            request.FILES
        )

        if form.is_valid():

            form.save()

            return redirect(
                "students"
            )

    else:

        form = StudentForm()

    return render(
        request,
        "upload_photo.html",
        {
            "form": form
        }
    )

upload_photo.html

<form
    method="post"
    enctype="multipart/form-data"
>

    {% csrf_token %}

    {{ form.as_p }}

    <button type="submit">
        Upload Photo
    </button>

</form>

Display Image:

{% if student.photo %}

    <img
        src="{{ student.photo.url }}"
        alt="{{ student.name }}"
        width="150"
    >

{% endif %}

30. Django Image Upload Summary

Django provides ImageField and other tools for handling image uploads.

  • Install Pillow before using ImageField.
  • Use ImageField for image uploads.
  • Use MEDIA_ROOT for media storage.
  • Use MEDIA_URL for media URLs.
  • Use multipart/form-data in upload forms.
  • Use request.FILES to access uploaded images.
  • Pass request.FILES to ModelForms.
  • Use upload_to to organize images.
  • Use photo.url to display an uploaded image.
  • Validate image size, format, and other requirements on the server.

📌 Key Points

  • ImageField is used for image uploads.
  • Pillow is required for Django ImageField.
  • request.FILES contains uploaded images.
  • Image upload forms require multipart/form-data.
  • MEDIA_ROOT defines the storage location.
  • MEDIA_URL defines the media URL prefix.
  • ModelForms simplify image-upload processing.
  • Use photo.url to display uploaded images.
  • Always validate uploaded images on the server.

🧠 Quick Quiz

Question: Which Django model field is specifically designed for uploading images?