File upload allows users to send files from their computer to a Django application. Common examples include uploading documents, resumes, assignments, PDFs, and other files.
Django provides FileField, request.FILES,
forms, and media settings to handle uploaded files.
enctype="multipart/form-data" and the Django view must process
the uploaded file through request.FILES.
File upload is the process of sending a file from a user's device to a web application.
Examples include:
A typical Django file-upload system uses several components.
FileFieldrequest.FILESMEDIA_ROOTMEDIA_URL
Django provides FileField for storing references to uploaded
files.
from django.db import models
class Student(models.Model):
name = models.CharField(
max_length=100
)
document = models.FileField(
upload_to="documents/"
)
The uploaded file will be stored according to the configured media settings.
The upload_to option specifies the directory inside the media
storage where uploaded files should be stored.
document = models.FileField(
upload_to="documents/"
)
Another example:
assignment = models.FileField(
upload_to="assignments/"
)
MEDIA_ROOT specifies the filesystem directory where uploaded
media files are stored.
For example:
MEDIA_ROOT = BASE_DIR / "media"
Uploaded files are stored under this directory according to their
upload_to configuration.
MEDIA_URL defines the URL prefix used to access media files.
MEDIA_URL = "/media/"
This setting is different from MEDIA_ROOT.
| Setting | Purpose |
|---|---|
| MEDIA_ROOT | Physical storage location. |
| MEDIA_URL | URL used to access media. |
A basic development configuration can look like:
MEDIA_ROOT = BASE_DIR / "media"
MEDIA_URL = "/media/"
The media directory can be created in the project folder.
from django.db import models
class Document(models.Model):
title = models.CharField(
max_length=200
)
file = models.FileField(
upload_to="documents/"
)
uploaded_at = models.DateTimeField(
auto_now_add=True
)
This model stores a title, uploaded file, and upload timestamp.
After creating or changing the model, create and apply migrations.
python manage.py makemigrations
python manage.py migrate
The database stores the file reference. The actual uploaded file is stored through the configured file storage.
The HTML form must use multipart/form-data.
<form
method="post"
enctype="multipart/form-data"
>
{% csrf_token %}
<input
type="text"
name="title"
>
<input
type="file"
name="file"
>
<button type="submit">
Upload
</button>
</form>
The multipart/form-data encoding allows the browser to send
file content along with normal form fields.
Without it, the uploaded file will not be submitted correctly through a normal HTML file-upload form.
enctype="multipart/form-data"
Django makes uploaded files available through
request.FILES.
uploaded_file = request.FILES.get(
"file"
)
The key should match the name of the HTML file input.
Suppose the form contains:
<input
type="file"
name="document"
>
The view can retrieve it with:
document = request.FILES.get(
"document"
)
from django.shortcuts import render
from .models import Document
def upload_file(request):
if request.method == "POST":
title = request.POST.get(
"title"
)
uploaded_file = request.FILES.get(
"file"
)
Document.objects.create(
title=title,
file=uploaded_file
)
return render(
request,
"upload.html"
)
Always check whether a file was actually submitted when the field is optional.
uploaded_file = request.FILES.get(
"file"
)
if uploaded_file:
print("File uploaded")
else:
print("No file selected")
The uploaded file object provides information about the file.
uploaded_file.name
For example:
resume.pdf
The name should not automatically be treated as safe input for arbitrary filesystem operations.
The uploaded file object also provides its size in bytes.
uploaded_file.size
For example, you can check whether a file exceeds an allowed size.
if uploaded_file.size > 5 * 1024 * 1024:
print("File is too large")
Applications often restrict uploads to specific file types.
import os
extension = os.path.splitext(
uploaded_file.name
)[1].lower()
if extension not in [
".pdf",
".doc",
".docx"
]:
print("Invalid file type")
File validation should be performed on the server.
You can validate the file size before saving it.
max_size = 5 * 1024 * 1024
if uploaded_file.size > max_size:
return render(
request,
"upload.html",
{
"error":
"File size is too large."
}
)
Here the maximum size is 5 MB.
A ModelForm can simplify file-upload handling.
from django import forms
from .models import Document
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = [
"title",
"file"
]
def upload_file(request):
if request.method == "POST":
form = DocumentForm(
request.POST,
request.FILES
)
if form.is_valid():
form.save()
return redirect(
"documents"
)
else:
form = DocumentForm()
return render(
request,
"upload.html",
{
"form": form
}
)
Notice that request.FILES is passed to the form along with
request.POST.
<form
method="post"
enctype="multipart/form-data"
>
{% csrf_token %}
{{ form.as_p }}
<button type="submit">
Upload
</button>
</form>
The multipart encoding is still required even when using a Django ModelForm.
A saved FileField provides information about the uploaded file.
{{ document.file.url }}
For example, an uploaded document can be linked using:
<a href="{{ document.file.url }}">
Download File
</a>
Before displaying a file link, check whether a file has been associated with the object.
{% if document.file %}
<a href="{{ document.file.url }}">
Download
</a>
{% endif %}
During development, Django can serve media files using 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 approach is intended for development, not as a general production media-serving solution.
enctype="multipart/form-data".request.FILES to a ModelForm.MEDIA_ROOT.MEDIA_URL.User Selects File
↓
Multipart Form
↓
POST Request
↓
request.FILES
↓
Validation
↓
FileField / ModelForm
↓
Save File
↓
MEDIA_ROOT
↓
Store File Reference
↓
Display / Download File
models.py
from django.db import models
class Document(models.Model):
title = models.CharField(
max_length=200
)
file = models.FileField(
upload_to="documents/"
)
forms.py
from django import forms
from .models import Document
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = [
"title",
"file"
]
views.py
from django.shortcuts import render, redirect
from .forms import DocumentForm
def upload_file(request):
if request.method == "POST":
form = DocumentForm(
request.POST,
request.FILES
)
if form.is_valid():
form.save()
return redirect(
"documents"
)
else:
form = DocumentForm()
return render(
request,
"upload.html",
{
"form": form
}
)
upload.html
<form
method="post"
enctype="multipart/form-data"
>
{% csrf_token %}
{{ form.as_p }}
<button type="submit">
Upload
</button>
</form>
Django provides convenient tools for handling uploaded files.
FileField in models.MEDIA_ROOT for file storage.MEDIA_URL for media URLs.multipart/form-data in upload forms.request.FILES to access uploaded files.request.FILES to ModelForms.upload_to to organize uploaded files.file.url to create links to uploaded files.FileField is used to store uploaded file references.request.FILES contains uploaded files.multipart/form-data.MEDIA_ROOT defines where uploaded files are stored.MEDIA_URL defines the media URL prefix.Question: Which Django object contains files uploaded through a multipart form?