File Upload with Forms
A snippet showing how to upload files using Django forms.
# forms.py
from django import forms
class UploadForm(forms.Form):
title = forms.CharField(max_length=120, required=False)
file = forms.FileField()
def clean_file(self):
f = self.cleaned_data["file"]
# Example basic validation - size limit 5 MB
max_mb = 5
if f.size > max_mb * 1024 * 1024:
raise forms.ValidationError(f"File too large. Max {max_mb} MB allowed.")
return f
# views.py
from django.shortcuts import render, redirect
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from .forms import UploadForm
def upload_view(request):
if request.method == "POST":
form = UploadForm(request.POST, request.FILES)
if form.is_valid():
f = form.cleaned_data["file"]
# Save using default storage (filesystem, S3, etc. based on settings)
path = default_storage.save(f"uploads/{f.name}", ContentFile(f.read()))
return render(request, "upload_done.html", {"path": path, "title": form.cleaned_data.get("title")})
else:
form = UploadForm()
return render(request, "upload.html", {"form": form})
# templates/upload.html
<div class="row justify-content-center">
<div class="col-md-8 col-lg-6">
<form method="post" enctype="multipart/form-data" class="bg-white border rounded p-3">
{% csrf_token %}
<h5 class="mb-3">Upload a file</h5>
{{ form.as_p }}
{% if form.errors %}
<div class="alert alert-danger">Please fix the errors below.</div>
{% endif %}
<button type="submit" class="btn btn-primary w-100">Upload</button>
</form>
</div>
</div>
# templates/upload_done.html
<div class="alert alert-success">
<h6 class="mb-1">Upload complete</h6>
<div>Saved to: <code>{{ path }}</code></div>
{% if title %}<div>Title: <strong>{{ title }}</strong></div>{% endif %}
</div>
# urls.py
from django.urls import path
from .views import upload_view
urlpatterns = [
path("upload/", upload_view, name="upload"),
]
Explanation:
-
Always include
enctype="multipart/form-data"on the form tag for uploads. -
Access uploaded files via
request.FILES; validate size/type inclean_file. -
Use
default_storageto stay storage-backend agnostic (local FS, S3, etc.).
- Category Forms & Validation
- Total Views 1840
- Last Modified 30 September, 2025
- Tags #forms #file upload #media #validation
Previous snippet
Custom Validators Example
Next snippet