To Do List - Part 1: Installing Django

This tutorial is part of a series on creating a To Do List app. If you just want to start up a new Django project, you're in the right place.

This tutorial is going to cover how to start a new Django project.

These are the steps we’re going to take to get set up:

  1. Create a virtual environment

  2. Install Django


You will need python and git installed on your machine.

If you are new to git, then I recommend this tutorial by the Odin Project. This guide by RealPython has detailed instructions on installing Python on each kind of operating system.


I am starting with a Github repository with just a and a .gitignore. The finished code for this tutorial can be found here. If you like, you can fork the repository as a shortcut.

Step 1: Create a Virtual Environment

All python projects begin with creating a virtual environment.

What is a virtual environment?

A virtual environment is a directory that will store all the packages for your project including Python and Django. With a virtual environment, you can pick and choose which Python packages your project will have access to and which version.

The advantage of virtual environments they isolate the dependencies for each of your Python projects. You can have two projects on the same machine each running different versions of Python.

How to create a virtual environment

Navigate to the directory where you want to put your project and open it in your IDE (I’m using VScode).


cd django-todo-tutorial
code .

To create your virtual environment, run the following command in the terminal:

python3 -m venv venv

Once the command has finished running, you should see a new folder called venv.

The virtual environment contains three folders: bin, include and lib. The bin folder contains the code you will use to activate and deactivate your virtual environment. The include folder is empty and the lib folder will contain all the packages you will install.

By default, the latest version of Python 3 installed on your machine is used. If you need to use a specific version of Python, then I recommend pyenv (docs).

Don’t push your virtual environment to GitHub

It’s not necessary to push the virtual environment with the rest of your code. The virtual environment will have thousands of files and take up a lot of memory.

It might seem logical to upload it to GitHub so you can set up your project on another machine but it is bad practice. Instead, you should create a separate virtual environment on each machine. Later in this tutorial, I will show you how to create a requirements.txt file so each virtual environment will have the correct packages and versions installed.

How to activate a virtual environment

Run the following line to activate your virtual environment:

source venv/bin/activate

Once your virtual environment is active, you will no longer need to use python3 to execute Python commands. You can use Python instead.

Step 2: Install Dependencies

We will use a package manager called pip to install our dependencies.

Often, pip is automatically installed with Python. If not, consult the official pip documentation to install it.


Most beginners tutorials won’t teach you how to manage your dependencies properly, but I think all beginners should learn.

I like using pip-tools to manage my dependencies. Most Python projects will have a file called requirements.txt which lists the packages and their versions, but it doesn’t get updated automatically when a new package is installed.

My approach is to list my packages in and compile it to produce requirements.txt. I’ve written a whole post on the subject, which you can read here.

First, we need to install pip-tools, which we will need to compile the requirements:

Then create a file called (.in is short for ‘input’). Add the following:



We will install the latest versions of django and django-environ. I’ve included django-environ because it allows you to create a file of environment variables which you can use to hide sensitive data like the project secret key and API credentials.

Install pip-tools

We need to install pip-tools so we can compile our to create requirements.txt. Run the following line in your terminal:

pip install pip-tools

Create requirements.txt

The next step is to compile the requirements. Run the following line in your terminal:

pip-compile --output-file=requirements.txt

This will compile to produce a file called requirements.txt.

If you get this error: command not found: pip-compile, it’s because pip-tools is not installed in your virtual environment.

You will notice that requirements.txt contains more packages than Mine looks like this:

# This file is autogenerated by pip-compile with python 3.8
# To update, run:
#    pip-compile --output-file=requirements.txt
    # via django
    # via django
    # via -r
    # via -r
    # via django

This is because most packages have dependencies of their own. To install Django in our virtual environment, we must also install asgiref, backports-zoneinfo and sqlparse.

This is why I always recommend creating a file. It helps us keep track of the packages we have installed. The compiled requirements.txt file will state why the package is required.

Install Django

This is the bit where we finally install Django.

pip install -r requirements.txt

Step 3: Create a Django Project

Now that we have installed Django, we can create a project.

django-admin startproject <project-name> .

The convention is to name the project after your site. If you’re building something generic, like a blog or a to-do list app, then I’d advise you don’t name your project “blog” or “todo”. This is because in the next step, we will create an app. For my to-do list tutorial, I will have an app called “todo” which means I need to find another name for my project.

To keep things generic, I am going to follow the example of the Django official tutorial and call it “mysite”.

django-admin startproject mysite .

Include a dot after the project name to create the project in the current directory. If you prefer, you can leave out the dot, which will place the project in a new directory with the same name as your project.

What are the files for? is an empty file. The presence of in a folder indicates that the folder is also a Python module. In your Django project, you will see that imports use dots rather than slashes to import code e.g. from blog.models rather than from blog/ This wouldn’t work if the blog folder didn’t have an file. You can read more about this file in the Python docs. WSGI stands for Web Server Gateway Interface. Django is a web framework but it’s not a web server. WSGI is the technology that provides the interface between the Django application and the web server (provided by gunicorn or nginx).This article by App Dynamics offers a thorough explanation. The Django docs also has a page on WSGI (link). ASGI stands for Asynchronous Server Gateway Interface. It’s like WSGI but it can handle asynchronous requests. contains the settings for our project. is a file that maps URL patterns as typed by the user to Django views (functions that process requests from the user). This file is known as routes in other web frameworks. is a Python script that can be run to perform management commands such as starting the server, making migrations and creating a superuser.

Step 4: Test the server

In the terminal, run the following command. Make sure your terminal is in the same directory as

python runserver

If you get this error: can't open file '': [Errno 2] No such file or directory, then you need to navigate to the directory that contains in your terminal.

You should get the following output in your terminal:

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python migrate' to apply them.

July 21, 2022 - 21:21:05
Django version 4.0.6, using settings 'mysite.settings'
Starting development server at
Quit the server with CONTROL-C.

In your browser, navigate to localhost:8000. You should see something like this:

![A screenshot of localhost:8000 after installing Django. It has an illustration of a rocket and the words "The install worked successfully! Congratulations!"

"You are seeing this page because DEBUG equals true is in your settings file and you have not configured any URLs.]( align="left")

According to the output, there are 18 unapplied migrations. Let’s run those.

Step 5: Run migrations

When we ran python runserver, Django created a database. In your project folder (same folder as, you should now have a file called db.sqlite3. This file is a SQLite database.

One of my favourite things about Django is it can create database for you. SQLite isn’t the kind of database you would use for a project that will produce gigabytes of data. However, for small, personal projects, it’s very convenient. You can always switch to a more feature-rich database like PostgreSQL later in your project.

If you are using VScode, I strongly recommend you install an extension to view the contents of the database (find out more).

You can run migrations by running the following command in your terminal:

python migrate

Why do we need to run migrations?

In the previous step, starting the server created an empty SQLite database.

Django needs to create 10 tables in the database to work properly. These include tables to store users, permissions and sessions.

The migration files specify what tables will be created, what columns those tables with have and what kind of data can be stored in each column.

I have written a beginner’s guide to migrations, which you can read here.

Step 6: Create a superuser

Django has an admin area where you can explore your data. However, you will need to create a superuser so you can log in.

In the previous step, we created a table in the database for users by running migrations. Now we can create a user.

python createsuperuser

Follow the prompts to provide a username, email and password.

If you ever forget your password, I have a guide on how to change it.

After creating the superuser, check that you can log into the admin area.

Go to localhost:8000/admin and log in with the same credentials.

When you log in, you will see a screen like this:

Screenshot of Django admin. There are two models available to click on: Groups and Users.

You will be able to view your superuser in the users table.

Step 7: Secure your secret key

Every Django project has a secret key. It’s used to generate hashes for many of Django’s security features.

Secret keys should not be pushed to Github. Therefore, you need a file that your Django application can access but is hidden from everyone else.

What we are going to do is create a file called .env which will store the secret key. Our file will import the secret key from that file.

In Step 2, we installed django-environ, a package that will help us read environment variables from .env.

If you missed that step, you can install it with the following command:

pip install django-environ

Create the .env file

Create a file called .env in the same directory as

Add the following code, but with your own secret key:


Make sure there are no quotations around the key.

Don’t commit .env!

Add .env to your gitignore.

Update settings

Go to, add import environ:


import environ

After your imports, add the following line. This will read the values in the .env file.


env = environ.Env()


If you get errors, then have a look at my settings on GitHub.


In this tutorial, we created a Django project. This tutorial covered:

  • Setting up a virtual environment

  • Installing Django

  • Creating a Django project

  • Setting up our application database

  • Creating a superuser to access the admin area

  • Securing the secret key

Next Up

Part 2: Apps & Models