Getting Started with Django, Part 1
Django is a Python-based web framework that traces its roots all the way back to 2003. The first public release was in July 2005 and it’s been free and open source ever since. The framework is used by big projects, including Instagram, Clubhouse, and Mozilla.
In this tutorial, you’ll learn about the Django MTV model and project structures, and how to set up your admin credentials. You’ll also learn about Django apps, URL routing, models, forms, templates, and how to render data in templates. In Part 2 of this series, you’ll apply CRUD (Create, Read, Update, and Delete) operations to create a useful Todolist web application.
The Django framework follows a Model-view-controller (MVC) architectural pattern. Let’s introduce that pattern in the following section.
MVC pattern
The Model-view-controller architectural pattern is commonly used for designing web applications. The benefit of this practice is to separate the logic of your app to three elements: model, view, and controller.
As stated by Martin Fowler in his 2003 book Patterns of Enterprise Application Architecture, the controller receives the user request, sends the appropriate message to the model, receives the response from the model, and passes the response to the appropriate view for display.The Django framework adapts this approach with a slight tweak. It uses a Model-template-view (MTV) framework where the user interacts with the database through the model and sends a request. The model returns the request to the appropriate view which passes it to the templates for display.
Django set up
You can find the finished source code for this project in this GitHub repo. If you prefer to follow along, you can set up Django, initiate a virtual environment, and install it with this command:
python3 -m venv venv; . venv/bin/activate; pip install --upgrade pip
pip install django
In this tutorial, we’ve set up Django v4.1.2. However, you can use your own version because it won’t differ much for this basic tutorial.
Todo Django project structure
Now, let’s build a todo project with Django. First, create a new directory called DJANGO_TODO
and navigate to it:
mkdir DJANGO_TODO
cd DJANGO_TODO
Next, build the Django boilerplate:
django-admin startproject todo .
The startproject
subcommand with the .
will create the todo project which has the Django project structure inside the current working directory (DJANGO_TODO
).
So, the tree of this structure (excluding the virtual environment directory) will be:
.
├── manage.py
└── todo
├── asgi.py
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
Note: If you omit the dot in the django-admin startproject
command, you’ll have two todo’s directories: one at the current directory and the other will be the child directory with the manage.py
file. To avoid the confusion of the two directories, we used the DJANGO_TODO
as the base URL of the todo project and todo as the project directory.
Each file has a purpose:
manage.py
executes specific administrative Django tasks similar to thedjango-admin
command-line utility.asgi.py
contains the asynchronous gateway interface (ASGI) configurations for your Django project. You probably won’t seeasgi.py
file if you’re using an earlier Django version. This file is installed by default when starting the Django project. WSGI or ASGI configurations are recommended configurations for deploying your Django project.__init__.py
allows the project to be a Python package that can be imported elsewhere. Note the__init__.py
is a generic Python file used to make Python packages; it’s not Django-specific.settings.py
contains the configurations of the Django project.urls.py
contains the URL routings for the Django project.wsgi.py
contains the web server gateway interface (WSGI) configurations of your Django project.
Running the web server
To run the Django web server, use the runserver subcommand on the command line:
python manage.py runserver
Open your browser and navigate to https://localhost:8000
. You’ll see the following starter page:
If you look at the terminal, you’ll see the following warning:
This means there aren’t any database migrations already done for this project. Django by default has a SQLite database set up in its configuration settings. So, let’s apply the database migrations:
python manage.py migrate
Now, when you run the server again, you’ll see the earlier warning is omitted.
Creating the admin
Django has a set of applications installed by default, such as the admin app. We want to set up the admin credentials because we want to use this admin to enter and retrieve data in our todo project.
You can create the admin username, email, and password with the following:
python manage.py createsuperuser
After you enter them and don’t encounter any errors, you’ll see this message: “Superuser created successfully.”Now, run the server back again with python manage.py
runserver and head over to https://localhost:8000/admin
. You’ll see a login prompt:
Log in with your registered admin credentials. You’ll then be redirected to the admin page. You can use this page later in this tutorial to create your todo items.
Creating and configuring a Django app
A Django app is used to group a project’s functionalities. For this todo project, we will create an application for the tasks. If you want to extend it further, you can add other apps as you need, like an app for history, another app for user information, and so on.
There are Django apps created by default when starting a Django project, like admin and auth. There are also third-party apps created for specific needs. The way an app is structured makes it easy to configure. Apps are created as subdirectories to the project directory.Let’s see that in action and create the tasks app:
python manage.py startapp tasks
Now, the tasks app
is created with a subdirectory after the same name. Inside that directory, you’ll see files like the following:
__init__.py
which allows Python packaging as in the todo directory.admin.py
which contains the admin definitions for the app.apps.py
which contains configuration parameters for the app.models.py
which contains the database configurations for the app.tests.py
which contains test cases for the functionalities of the app.views.py
which contains the view functions for the app.
Now, open the todo/settings.py
file and app the new app tasks into the INSTALLED_APPS list:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'tasks',
]
URL routing
To test the new tasks
app, you need to route the URLs that you want to access the app from. To configure the content that should be represented, edit the tasks/views.py
:
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello world!")
This index view method returns an HTTP response of a “Hello world!” string. To receive this response, you need to configure what URL this content will be displayed on.
So, create a new file tasks/urls.py
for the tasks URLs and fill in the following:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='list')
]
Django looks for the urlpatterns
variable to search for the requested URL. This variable is a list of Django paths. At this time, we have one URL, which is the root URL. The path()
function takes the path directory, the views method, and the name of that URL. The list
name will be used later in this tutorial.
To configure all URLs contained in the tasks
app to the whole todo
project, include the tasks
URLs in the urlpatterns
list for the todo project in the todo/urls.py
file:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('tasks.urls'))
]
Now, open the browser and enter https://localhost:8000
. You’ll see the “Hello world!” message on the screen.
Django templates
Templates in Django define the layout of the page format sent to the user after the view method is invoked.
Create a new directory, templates
, inside the tasks
app and then create another directory inside named after the app (tasks
).
In that directory, create a new HTML file called list.html
(i.e. this tasks/templates/tasks/list.html
path):
<h1>To Do</h1>
To display this h1 heading to the user, you need to configure the view method to render that template. Open the tasks/views.py
file and edit it to the following:
from django.shortcuts import render
def index(request):
return render(request, 'tasks/list.html')
The render function is a Django shortcut to render the Django templates. In this case, the function takes the request sent by the user and the template path (tasks/list.html
).
To view the template on the browser, open the localhost:8000
. You’ll see the To Do h1 heading is displayed.
Django models
To set up a database in Django, you need to create models in the models.py
file. We will use SQLite, the default database engine set up by Django. We will interact with it through Django Object-Relational Mapper (ORM) which deals with objects instead of native SQL queries.
Open the tasks/models.py
and enter the Task
class as follows:
from django.db import models
class Task(models.Model):
text = models.CharField(max_length=200)
is_done = models.BooleanField(default=False)
created_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.text
The Task model has three attributes:
text
, a string field to represent the text of the todo item. The length can’t be 200 characters.is_done
, a boolean field to show whether the todo is done or not. Its default value is False.created_date
, a date and time field. Theauto_now_add
option, here, automatically sets the creation date to now when the todo item is created.
Right now, Django doesn’t know about the models in this app. To make the migrations, use the makemigrations
command:
python manage.py makemigrations
When you run that command, Django searches for any change in the models.py
files for all Django apps listed in the INSTALLED_APPS
list. When Django finds a new model.py
file, it creates a new migration file for the app like this:
To apply the recently added migration file to the database, use the migrate
command:
python manage.py migrate
To do operations on this Task
model, you need to configure the model in the tasks/admin.py
file:
from django.contrib import admin
from .models import Task
admin.site.register(Task)
Go to the admin page on your browser:
As you can see, the Task
model has been already set up. If you click on the “Add” button, you’ll see the following fields:
Add your todo items in the text box of the text attribute.
The following items are added to that model:
Rendering data in templates
To render data in templates, you need to pass your desired objects from views to templates. You can edit the index
view method in the tasks/views.py
as follows:
from django.shortcuts import render
from .models import Task
def index(request):
tasks = Task.objects.all()
context = {'tasks': tasks}
return render(request, 'tasks/list.html', context)
The tasks
instance here is a QuerySet in Django, which is iterable. When you iterate over it, you’ll get all the entries of tasks stored in the database.
To display all the todo items in the root URL, you need to edit the list template in the tasks/templates/tasks/list.html
path:
<h1>To Do</h1>
{% for task in tasks %}
<div>
<ul>
<li>{{task}}</li>
</ul>
</div>
{% endfor %}
Open the localhost:8000
and you’ll see the bullet points of your items:
Learn more about using Django
Now that you’ve got the foundations in place, are you ready to extend your Django project? Check out Getting Started with Django, Part 2 to learn how to create and use forms for CRUD operations.