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.
ImageField uses the Pillow
library to validate and process image files.
Image upload is the process of sending an image from a user's device to a web application.
Common examples include:
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.
| Field | Purpose |
|---|---|
| FileField | General file uploads. |
| ImageField | Image uploads with image validation. |
Use ImageField when the uploaded content is expected to be an
image.
Django's ImageField requires Pillow.
Install Pillow using:
python -m pip install Pillow
You can verify the installation using:
python -m pip show Pillow
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.
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/"
)
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/
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.
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.
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>
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.
Uploaded images are available through request.FILES.
photo = request.FILES.get(
"photo"
)
The key must match the name of the file input.
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"
)
Check whether the user actually selected an image.
photo = request.FILES.get(
"photo"
)
if photo:
print("Image selected")
else:
print("No image selected")
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.
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")
An application should validate uploaded images before storing them.
Common validation checks include:
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.
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.
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"
]
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.
<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.
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.
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 %}
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.
ImageField configuration.enctype="multipart/form-data".request.FILES.MEDIA_ROOT.MEDIA_URL..url.User Selects Image
↓
Multipart Form
↓
POST Request
↓
request.FILES
↓
Image Validation
↓
ImageField / ModelForm
↓
Save Image
↓
MEDIA_ROOT
↓
Store File Reference
↓
Display Image
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 %}
Django provides ImageField and other tools for handling image
uploads.
ImageField for image uploads.MEDIA_ROOT for media storage.MEDIA_URL for media URLs.multipart/form-data in upload forms.request.FILES to access uploaded images.request.FILES to ModelForms.upload_to to organize images.photo.url to display an uploaded image.ImageField is used for image uploads.request.FILES contains uploaded images.multipart/form-data.MEDIA_ROOT defines the storage location.MEDIA_URL defines the media URL prefix.photo.url to display uploaded images.Question: Which Django model field is specifically designed for uploading images?