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:
- Create a virtual environment
- 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
README.md 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
The virtual environment contains three folders:
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:
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.
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
requirements.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:
# requirements.in django django-environ
We will install the latest versions of
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.
We need to install
pip-tools so we can compile our
requirements.in to create
requirements.txt. Run the following line in your terminal:
pip install pip-tools
The next step is to compile the requirements. Run the following line in your terminal:
pip-compile --output-file=requirements.txt requirements.in
This will compile
requirements.in to produce a file called
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
requirements.in. Mine looks like this:
# # This file is autogenerated by pip-compile with python 3.8 # To update, run: # # pip-compile --output-file=requirements.txt requirements.in # asgiref==3.5.2 # via django backports-zoneinfo==0.2.1 # via django django==4.0.6 # via -r requirements.in django-environ==0.9.0 # via -r requirements.in sqlparse==0.4.2 # via django
This is because most packages have dependencies of their own. To install Django in our virtual environment, we must also install
This is why I always recommend creating a
requirements.in file. It helps us keep track of the packages we have installed. The compiled
requirements.txt file will state why the package is required.
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?
init.py is an empty file. The presence of
__init__.py 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/models.py This wouldn’t work if the
blog folder didn’t have an
__init__.py file. You can read more about this file in the Python docs.
wsgi.py: 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.py: ASGI stands for Asynchronous Server Gateway Interface. It’s like WSGI but it can handle asynchronous requests.
settings.py contains the settings for our project.
urls.py 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.
manage.py 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 manage.py runserver
If you get this error:
can't open file 'manage.py': [Errno 2] No such file or directory, then you need to navigate to the directory that contains
manage.py 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 manage.py migrate' to apply them. July 21, 2022 - 21:21:05 Django version 4.0.6, using settings 'mysite.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
In your browser, navigate to localhost:8000. You should see something like this:
According to the output, there are 18 unapplied migrations. Let’s run those.
Step 5: Run migrations
When we ran
python manage.py runserver, Django created a database. In your project folder (same folder as
manage.py), 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 manage.py 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 manage.py 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.
localhost:8000/admin and log in with the same credentials.
When you log in, you will see a screen like this:
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
settings.py 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
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!
.env to your gitignore.
settings.py, add import
# settings.py import environ
After your imports, add the following line. This will read the values in the .env file.
# settings.py env = environ.Env() environ.Env.read_env() SECRET_KEY = env(‘SECRET_KEY’)
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