← Back to Django Course | Chapter 11: Static Files & Media Handling | Lesson 6 of 8

File Upload Forms

A file upload form is like handing someone an envelope instead of just talking to them — the browser has to package the file specially so the server can unwrap it.

The Upload Form Template

The form tag needs method=post and enctype='multipart/form-data' for file uploads to work; a plain form without enctype will submit the filename as text only, not the file itself.

Example: The Upload Form Template

The form tag needs method=post and enctype='multipart/form-data' for file uploads to work; a plain form without enctype will submit the filename as text only, not the file itself.

markup
<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <label for="id_avatar">Avatar</label>
    <input type="file" id="id_avatar" name="avatar">
    <button type="submit">Upload</button>
</form>
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Handling the Upload in a View

Uploaded file data arrives in request.FILES, separate from regular form fields in request.POST. Both must be passed into a ModelForm bound to the request.

Example: Handling the Upload in a View

Uploaded file data arrives in request.FILES, separate from regular form fields in request.POST. Both must be passed into a ModelForm bound to the request.

markup
from django.shortcuts import render, redirect
from .forms import ProfileForm

def upload_avatar(request):
    if request.method == 'POST':
        form = ProfileForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('profile')
    else:
        form = ProfileForm()
    return render(request, 'upload.html', {'form': form})
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}

Validating Uploaded Files

A form using a FileField or ImageField automatically validates the upload through the field itself — calling form.is_valid() rejects missing or invalid files before form.save() ever runs.

Note: Add custom size/type checks inside a clean_<field> method on the form for stricter validation.

Example: Validating Uploaded Files

A form using a FileField or ImageField automatically validates the upload through the field itself — calling form.is_valid() rejects missing or invalid files before form.save() ever runs.

markup
from django import forms
from .models import Profile

class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['name', 'avatar']

form = ProfileForm(data, files)
if form.is_valid():
    form.save()
else:
    print(form.errors)
{# Django-only code -- models.py/views.py/urls.py/settings.py snippets, or template markup using Django template tags/variables -- can't run standalone via Judge0 or the browser preview, since it needs a real Django project. Only this course's pure-Python examples (example_lang == 'python', no Django imports) are actually runnable, so those still get the button below. #}
Common Mistakes
  1. Forgetting enctype='multipart/form-data' on the <form> tag, which silently prevents the file from being uploaded at all.
  2. Reading uploaded data from request.POST instead of request.FILES.
  3. Not validating file size or type before saving, allowing oversized or unexpected files to be stored.
Chapter Summary
  • File upload forms must set enctype='multipart/form-data' or the file data never reaches the server.
  • Uploaded files are accessed through request.FILES, not request.POST.
  • Every file input still needs a label and a name attribute like any other form field.
  • A form using a FileField/ImageField should be instantiated with both request.POST and request.FILES.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.