When I first started working with Django, one of the common tasks I encountered was uploading files and then displaying them back to users. Whether it’s images, PDFs, or documents, handling uploaded files is essential for many web applications. I’ve developed a simple approach that works perfectly for projects ranging from personal blogs to enterprise-level apps.
In this tutorial, I’ll walk you through how to upload files in Django and view those uploaded files directly in your browser. I’ll share working code examples and tips to ensure you can implement.
Understand File Uploads in Django
Django provides excellent built-in support for file uploads. When a user uploads a file through a form, Django processes it and stores it in a location you specify, typically in a media directory. The challenge often lies in making these uploaded files accessible and viewable on your website.
To make this happen, you need to:
- Create a form that allows file uploads.
- Handle file storage correctly.
- Serve the uploaded files so users can view them.
Let’s explore how to do this step-by-step.
Check out the Login system in Python Django
Step 1: Set Up Your Django Project and App
If you haven’t already, start by creating a new Django project and app:
django-admin startproject myproject
cd myproject
python manage.py startapp fileuploadAdd your app to the INSTALLED_APPS in settings.py:
INSTALLED_APPS = [
# other apps
'fileupload',
]Step 2: Configure Media Settings
To handle uploaded files, Django needs to know where to store and serve them.
In your settings.py, add:
import os
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')MEDIA_ROOTis the absolute path on your filesystem where files will be stored.MEDIA_URLis the URL endpoint to access these files.
Step 3: Create a Model to Store Uploaded Files
We’ll create a simple model with a FileField or ImageField to store the uploaded file reference.
In fileupload/models.py:
from django.db import models
class Document(models.Model):
title = models.CharField(max_length=255)
uploaded_file = models.FileField(upload_to='documents/')
def __str__(self):
return self.titleThis model stores a title and the file itself in a documents/ subfolder inside MEDIA_ROOT.
Run migrations:
python manage.py makemigrations
python manage.py migrateRead Python Django Form Validation
Step 4: Create a File Upload Form
In fileupload/forms.py, create a form to upload files:
from django import forms
from .models import Document
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ['title', 'uploaded_file']Step 5: Build Views to Handle Upload and Display
In fileupload/views.py, add views for uploading files and listing uploaded files:
from django.shortcuts import render, redirect
from .forms import DocumentForm
from .models import Document
def upload_file(request):
if request.method == 'POST':
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('file_list')
else:
form = DocumentForm()
return render(request, 'fileupload/upload.html', {'form': form})
def file_list(request):
files = Document.objects.all()
return render(request, 'fileupload/file_list.html', {'files': files})Step 6: Create Templates for Upload and Display
Create the templates folder fileupload/templates/fileupload/ and add:
upload.html
<!DOCTYPE html>
<html>
<head>
<title>Upload File</title>
</head>
<body>
<h1>Upload a File</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
<a href="{% url 'file_list' %}">View Uploaded Files</a>
</body>
</html>file_list.html
<!DOCTYPE html>
<html>
<head>
<title>Uploaded Files</title>
</head>
<body>
<h1>Uploaded Files</h1>
<ul>
{% for file in files %}
<li>
<strong>{{ file.title }}</strong> -
<a href="{{ file.uploaded_file.url }}" target="_blank">View File</a>
</li>
{% empty %}
<li>No files uploaded yet.</li>
{% endfor %}
</ul>
<a href="{% url 'upload_file' %}">Upload Another File</a>
</body>
</html>Check out How to Encrypt and Decrypt Passwords in Django
Step 7: Configure URLs
In fileupload/urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('upload/', views.upload_file, name='upload_file'),
path('files/', views.file_list, name='file_list'),
]Include these URLs in the main myproject/urls.py and add media serving during development:
from django.conf import settings
from django.conf.urls.static import static
from django.urls import path, include
urlpatterns = [
path('', include('fileupload.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)Step 8: Run the Server and Test
Start your development server:
python manage.py runserver- Visit
http://127.0.0.1:8000/upload/to upload a file. - After uploading, you’ll be redirected to the list page where you can click “View File” to see the uploaded file.
You can see the output in the screenshot below.


Check out Python Django Form Validation
Alternative Method: Use Class-Based Views
If you prefer class-based views, here is a quick example using Django’s generic views:
In views.py:
from django.views.generic import CreateView, ListView
from django.urls import reverse_lazy
from .models import Document
class DocumentUploadView(CreateView):
model = Document
fields = ['title', 'uploaded_file']
template_name = 'fileupload/upload.html'
success_url = reverse_lazy('file_list')
class DocumentListView(ListView):
model = Document
template_name = 'fileupload/file_list.html'
context_object_name = 'files'Update urls.py accordingly:
from django.urls import path
from .views import DocumentUploadView, DocumentListView
urlpatterns = [
path('upload/', DocumentUploadView.as_view(), name='upload_file'),
path('files/', DocumentListView.as_view(), name='file_list'),
]This method reduces boilerplate and leverages Django’s powerful generic views.
Read Login system in Python Django
Conclusion
Uploading and viewing files in Django is a common requirement, and once you understand the flow, it becomes straightforward. I prefer the method shown here because it cleanly separates concerns and uses Django’s built-in features without extra dependencies.
Remember to secure your media files properly if you are deploying to production. For example, use cloud storage or configure your web server to serve media securely.
If you follow these steps, you’ll have a robust file upload and viewing feature ready for your Django projects.
You may also read:

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.