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 in clean_file.
  • Use default_storage to stay storage-backend agnostic (local FS, S3, etc.).
  • Category Forms & Validation
  • Total Views 1839
  • Last Modified 30 September, 2025
  • Tags #forms #file upload #media #validation
Previous snippet
Custom Validators Example
Never miss a story on Django.wiki

Subscribe for fresh tutorials, snippets, and updates.

By subscribing you agree to our Privacy Policy.