How to Upload a File in Django
- Set the Django Environment
- Setup Django Project
- Test the Server
-
Update
settings.py
File - Create a Model
- Create a Form to Upload Files
- Add Views
-
Configure the
urls.py
File - Testing
This article will walk you through how to upload files in Django. We will create a simple application with a simple form to fill in details and select a file. Also, display all the uploaded files in a table underneath.
Before we proceed, it’s recommended to create a new folder or directory for this project to keep things organized.
Set the Django Environment
For this tutorial, we will use a virtual environment. It’s not compulsory to use a virtual environment, but it’s a good practice to have a unique virtual environment for every project.
To build a virtual environment, we need a Python package, virtualenv
. If you don’t have it on your machine, you can download it using the following command.
pip install virtualenv
Now that you’ve installed the package, let’s create the environment.
To create an environment, run the following command.
virtualenv environment
environment
is the name of the virtual environment we just created. This environment will have the Python version installed globally on your machine and no packages except the default ones.
To activate this environment and use it, run the following command.
environment\Scripts\activate
Now, since we are learning about Django, we need the Django library installed. Also, since we are learning to upload files, we need an additional Python package to deal with the images. The package name is Pillow
. Let’s install all the dependencies.
pip install django
pip install Pillow
Or,
pip3 install django
pip3 install Pillow
Note that at the time of writing this article, the latest Django version is 3.2
.
Setup Django Project
To set up a Django project, we first have to create a Django project, create an application, register that application, and make the initial migrations.
To create a Django project, run the following command.
django-admin startproject DjangoFileUpload
Now, change the working directory to this project using the following command.
cd DjangoFileUpload
To create an application inside the Django project, run the following command.
django-admin startapp Core
Or,
python manage.py startapp Core
Core
is the name of the application.
To register this application, enter the application’s name inside the list INSTALLED_APPS
in the settings.py
file.
settings.py
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"Core", # Here
]
Django needs a few models to work properly. For example, the authentication system or superuser won’t work without the initial migration. So, to make the initial migrations, run the following command.
python manage.py migrate
Output:
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
Test the Server
To run the server, use the following command. If everything went on error-free, you should see your Django server running at http://127.0.0.1:8000/
.
python manage.py runserver
Update settings.py
File
The uploaded files need to be stored somewhere. In Django, by default, all the uploaded files are stored in a media
folder. You can always change the folder’s name and the URL associated with it, but we will stick to the default naming convention.
To define the URL to the media files, MEDIA_URL
, and the path to the media folder, MEDIA_ROOT
, add the following statements in the settings.py
file.
settings.py
import os
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
Don’t forget to import the os
module. Otherwise, Python will throw an error.
Create a Model
To store the uploaded files, we have to create a model. The field in this model will hold the path to the uploaded file but not the file itself.
We will create a model Document
to store the details about the uploaded files.
Core\models.py
from django.db import models
class Document(models.Model):
title = models.CharField(max_length=200)
uploadedFile = models.FileField(upload_to="Uploaded Files/")
dateTimeOfUpload = models.DateTimeField(auto_now=True)
The model has a title
field of a character type to store a custom title for the uploaded file, and dateTimeOfUpload
will store the date and time of file upload. The date-time field would be automatically set when the model object is created.
To store the files, we are using FileField()
. This type covers all sorts of files. But if you wish to be a bit specific with images, you can use the ImageField()
to store the images. For all the other fields, you have to stick to FileField()
.
The upload_to
parameter is used to define the folder, where the files of this model will be uploaded inside to media
folder.
Before we use this model, we have to make migrations and migrate them. For that, run the two following commands.
python manage.py makemigrations
python manage.py migrate
Create a Form to Upload Files
Inside the Core
application or folder, create a new folder, namely, templates
. Inside this folder, create another folder, namely, Core
. This should be the name of your application. Lastly, make a new file inside this folder, namely, upload-file.html
.
Now you should have a file structure like this.
DjangoFileUpload/
DjangoFileUpload/
__init__.py
asgi.py
settings.py
urls.py
wsgi.py
db.sqlite3
manage.py
Core/
migrations/
templates/
Core/
upload-file.html
__init__.py
admin.py
apps.py
models.py
tests.py
views.py
Inside the upload-file.html
, add the following HTML.
Core\templates\Core\upload-file.html
<!DOCTYPE html>
{% load static %}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Django File Upload</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
* {
font-family: "Roboto";
}
body {
background-color: #F5F5F5;
}
form {
background-color: #FFFFFF;
padding: 25px;
}
table {
width: 100%;
text-align: center;
margin-top: 25px;
padding: 25px;
background-color: #FFFFFF;
}
table tr td {
padding-top: 15px;
}
</style>
</head>
<body>
<form action="{% url 'Core:uploadFile' %}" method="POST" enctype="multipart/form-data">
<input type="text" name="fileTitle" placeholder="Enter a title">
<input type="file" name="uploadedFile">
{% csrf_token %}
<input type="submit" value="Upload">
</form>
<table>
<tr>
<th>ID</th>
<th>Title</th>
<th>File Path</th>
<th>Upload Date & Time</th>
</tr>
{% for file in files %}
<tr>
<td>{{ file.id }}</td>
<td>{{ file.title }}</td>
<td>{{ file.uploadedFile.url }}</td>
<td>{{ file.dateTimeOfUpload }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
Inside the table, we will display some details about the uploaded files.
Add Views
To display the HTML template and information on it and store and handle the file uploads, we will create a view uploadFile()
.
Refer to the following code
Core\views.py
from . import models
from django.shortcuts import render
def uploadFile(request):
if request.method == "POST":
# Fetching the form data
fileTitle = request.POST["fileTitle"]
uploadedFile = request.FILES["uploadedFile"]
# Saving the information in the database
document = models.Document(title=fileTitle, uploadedFile=uploadedFile)
document.save()
documents = models.Document.objects.all()
return render(request, "Core/upload-file.html", context={"files": documents})
This view renders the HTML template we just created in the previous section. The form in the HTML template is submitted to the same URL and handled in this view. If the request’s method is POST
, we fetch the information entered in the form and the file uploaded, store that information in the model and save the model.
Otherwise, in the general case, we fetch all the files that were uploaded and send them in a context dictionary to display on the HTML template.
Configure the urls.py
File
Lastly, let’s set up the URLs. Before we proceed, create a new file, namely, urls.py
inside the Core
application or folder. This file will hold all the URLs associated with this Django application. It’s a good practice to have a separate urls.py
file for every Django application.
Inside this file, add the following code.
from . import views
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
app_name = "Core"
urlpatterns = [
path("", views.uploadFile, name="uploadFile"),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
We have added a URL pattern for the HTML template upload-file.html
. Also, we have added one more URL for the media files. We will use the constant variables we declared in the settings.py
file.
Since we created a new urls.py
file inside the Core
application, we have to link the URLs defined here with the main project.
To do that, add the following statement inside the urlpatterns
list in DjangoFileUpload\urls.py
path("", include("Core.urls")),
Your file should look something like this.
File: DjangoFileUpload\urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("Core.urls")),
]
Testing
Congratulations! Now it’s time to test the project. Follow the steps below.
-
Start the server using the command -
python manage.py runserver
-
Go to the URL
http://127.0.0.1:8000/
-
Fill the form with a title, select a file, and submit the form.
Now you should see some details about the file in the table underneath the form.
Moreover, if you’ll check your working directory, you’ll see that a folder by the name of media
has been created, and inside this folder, there is another folder by the name of Uploaded Files
. This folder contains all the uploaded files.
You can upload photos, videos, programs, PDFs, JSON files, HTML files, etc. Note that the uploading time depends on the size of the file, so have patience when uploading.