Django For Beginners

Click to share! ⬇️

Django For Beginners

Django is a popular web framework built with Python that allows developers to quickly create maintainable web applications. In this tutorial, we’ll take a look at Django by getting it installed and setting up a simple project. Next, we’ll take a look at how models, URL patterns, views, and templates are used in Django to create powerful modular code for a web application. Django is a large software project with hundreds of features, but we’ll try to make it as understandable as possible. Let’s get started with Django.

What Is Django

When Looking at the official website, we learn that Django as a Python web framework that allows you to rapidly develop web projects in a clean, pragmatic design. A web framework is a collection of tools used to build web applications and websites. Django comes with tools like an object-relational mapper, or ORM, which helps us make database queries. It also offers URL routing which determines what logic to follow depending on the URL of a web request. HTML templating is a another feature of Django which facilitates viewing the data as HTML in a web browser. Django itself is not a programming language. Python is the programming language that Django was built with. Django is also not a web server but it does have a built-in web server for local development.

Installing Django

You may want to set up a Python Virtual Environment to begin, but it is not mandatory. To install Django, you first need the latest version of Python installed on your machine. It is quite easy to do, by simply following the instructions at the main Python website. This will also install PIP, the package manager for Python. Once ready, all you need to do is open a terminal window and type the following command.

pip install django

This installs the latest version of Django on your computer. You can check the status of Django like so at a Python command prompt.

>>> import django
>>> django.get_version()

That should be all you need to do in order to get started!

Create A Django Project

Django provides a simple command to scaffold out a new project for you. Before you run that command you want to navigate to a directory where you will store your project. For us, that will be in C:python. From here, I’ll create the initial set of files for our Django project using a command that comes with Django which is called Django admin. To create a project, we can type startproject and then the name of our project. We can just call it djangotutorial. We can type out the following command and then press enter.

python $ startproject djangotutorial

You will see that a new folder of djangotutorial is now in the current folder. In other words, we now have a Django project started in C:pythondjangotutorial. Now, I’ll open that folder using PyCharm, a fantastic Python IDE. Here we can see the outline of files created for a new Django project.

django new fresh project

Inside of the djangotutorial folder, there’s a file called There is also an inner djangotutorial folder that contains four files. These are,,, and Let’s take a look at what each of these files does. The file is used to run various commands for our project. The file tells Python that this folder contains Python files. Also known as dunder init. The file configures Django concepts like apps, middleware, templates, and so on. The file is the routing file, and routes http requests based on the URL. The, or wuzgi, file, provides a hook for web servers, such as Apache or Nginx.

With these files generated, we’re ready to run our project for the first time. We can start by navigating into the inner djangotutorial folder in our terminal. From here we can type ls and we should see the file. To run the server, we can type the command python runserver and we’ll see some output like below.

djangotutorial $python runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 17 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.
January 31, 2020 - 14:45:51
Django version 3.0, using settings 'djangotutorial.settings'
Starting development server at
Quit the server with CTRL-BREAK.

The Django server is now running. We can visit in the browser and we should see a nice Django splash screen.

Django Splash Screen

It worked! We can now see the default screen that Django makes when we create a new Django project. From here, our basic project has been generated and we’re ready to customize and add features. You might also notice that we have a db.sqllite file in the project now, that wasn’t there before. This is because when you run the runserver command for the first time, Django creates this file so that it has a database to work with.

Django Apps

A Django app is a component within a Django project. It is a folder with a set of Python files inside of it. A Django project is usually comprised of several different apps, each serving a different purpose. There may be a forum app, a wiki app, or a blog app. Each one would have its own folder within the Django project. The official docs reference creating a Polling application, and we might give that a shot in a later tutorial. For now, we’ll build an app for Dogs. We’ll call it DjangoDogs. To build out our app, we’ll go to the Terminal and navigate inside of our project to the folder where is located. Now we want to create the app. We can do this by typing the following command at the terminal.

djangotutorial $python startapp djangodogs

django startapp command result

We can now see that several files were added, including a migrations folder. To finish adding our Django app to the project, we have one more step. We’ll need to navigate inside of the djangotutorial folder and then go to the file. Inside of the settings file, we’ll scroll down until we find the installed apps setting. At the end of this list, we’ll add the string, djangodogs. The other apps that are on this list are default apps that come with Django. We need to edit this setting whenever we install or create a new Django app. Here is the file, with our new entry highlighted.

Django settings for djangotutorial project.

Generated by 'django-admin startproject' using Django 3.0.

For more information on this file, see

For the full list of settings and their values, see

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'not_the_real_keygo^4gs&^!1d$z7d6#q=)wqx4rt0!q'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True


# Application definition



ROOT_URLCONF = 'djangotutorial.urls'

        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [

WSGI_APPLICATION = 'djangotutorial.wsgi.application'

# Database

    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

# Password validation

        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',

# Internationalization



USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)

STATIC_URL = '/static/'

The Files of a Django App

File Purpose Configuration and Initialization Data Layer Admin Interface URL Routing Control Layer Tests the app Holds the migration files

The file controls settings specific to this app. The file offers Models in Django and is used to construct database schema and queries. The file defines a Django admin interface for the app where you can see and edit the data related to this app. The file can be used for URL routing specific to this app. The file defines the logic and control flow for handling requests and defines the HTTP responses that are returned. The file is used for writing unit tests for this app. Finally, the migrations folder holds files that Django uses to migrate the database as we create and change the database schema over time. This gives us a great overview of what an App is with regard to a Django project.

Django Routing Views Models Templates

django routing views models templates

It’s important to understand the underlying architecture when working with a web framework. Django is an MVC framework, or model view controller architecture, however, Django uses some different names for these. The four concepts to understand in Django are URL Patterns, Views, Models, and Templates. Each of these has a specific job.

URL Patterns: When a Django application receives a web request, it uses the URL patterns to decide which view to pass the request to for handling. In this project, the URL patterns are defined at djangotutorial/

Views: A View in Django takes an HTTP request as an argument and returns an HTTP response. Our views are defined at djangodogs/ Views provide the logic, or control flow portion of the project.

Models: When you want to perform queries against the database, each view can leverage Django models as needed. The models for the djangodogs app are located in djangodogs/ A Django model is a class with attributes that define the schema of a database table. These classes offer built-in methods for making queries on the associated tables.

Templates: Each view that is defined can also leverage Django templates that provide the presentation layer of what the HTML response will look like. Each template is a file that consists of HTML along with extra template syntax for variables, loops, and other control flow. Template files can be placed in a folder called templates for consistency.

Configure Your Django Homepage

For this project, we want to finally render a webpage using Django. We are going to do that right now. The first thing we need to do is to add a templates directory into our djangodogs app. Here we go.

create new directory in Pycharm for Django project

In the templates folder, we now need to add an Html file that our app can render.

home html for django app

Perfect. Now, we just want to add the most minimal of HTML markup so we can render a page.

<html lang="en-US">
    <meta charset="UTF-8">
    <title>Hello Django!</title>
<h1>Hello Django!</h1>

In order to load a template, we need a view to complete this task for us. If this sounds funny to you, you can think of views in Django kind of like controllers if you are thinking about this in a more traditional MVC approach. In Django, a view is actually a controller. Here is how we can configure our

from django.shortcuts import render

def home(request):
    return render(request, 'home.html')

In this code, we simply define a function named home(). It accepts an HTTP request and uses that to render the home.html file we just created in the prior step. You can see the render() function here takes two arguments. The first is the request, and the second is the template to display.

We can configure our like so.

from django.conf.urls import url
from djangodogs import views

urlpatterns = [
    url(r'^$', views.home, name='home'),

The purpose of the regular expression here is to match the root URL which is a slash(/). The carrot dollar sign does the trick for us here, and it is the first argument to the url() function. Now, when the web request comes into the application, we want to trigger the home() function in the file. The second parameter to url() accomplishes this goal. Lastly, we name this pattern home, which is like a named route. Now when we visit the home page of our Django project, we have success!

hello django homepage

So we can see rendering a web page in Django is as easy as one, two, three.

django render page

from django.urls import path

Regular expressions can be a bit daunting. As such Django also offers the ability to define routes using a much simpler syntax with the path() function. Here we update our file to reflect that change, and everything still works perfectly.

from django.urls import path
from djangodogs import views

urlpatterns = [
    path('', views.home, name='home')

Passing an ID via a Route

The combination of home url, view, and template above would likely be used to display a listing of dogs. It is like the home page for the dogs resource. Now, what about when you want to drill down on one item in the collection and view details about that item? In this case, if we want to view the specific details about a Dog, we want to pass along an ID via the url pattern. Imagine we have 10 different dogs in the database and each has a unique ID. We can pass that ID and get those details. Here is how we can set that up.

from django.urls import path
from djangodogs import views

urlpatterns = [
    path('', views.home, name='home'),
    path('dogs/<id>/', views.dog_detail, name='dog_detail'),

The snipped above is saying what we can visit an url like – and that would send the ID of 7 along in the request. In our file, we can test this out by returning an HttpResponse along with the given id.

from django.shortcuts import render
from django.http import HttpResponse

def home(request):
    return render(request, 'home.html')

def dog_detail(request, id):
    return HttpResponse(f'<h1>Dog with id {id}</h1>')

python path with id pass to view

This shows how passing an ID via the URL works in Django. Now, once we have a database implemented, we can use that ID to query the database to get details about a given Dog.

Passing Data To Template From View

Instead of returning an HttpResponse directly from the view, let’s now render a template file and pass the data from the function in the view to the template. We’ll also display the ID in that template using interpolation.

from django.shortcuts import render

def home(request):
    return render(request, 'home.html')

def dog_detail(request, id):
    return render(request, 'dog_detail.html', {'id': id})


<html lang="en-US">
    <meta charset="UTF-8">
    <title>Dog Detail!</title>
<h1>Dog with id of {{ id }}</h1>

url id to view to template

Introducing Django Models

Models refer to the data layer of a Django application. The concept is familiar if you have worked with any type of MVC project in various programming languages or frameworks. The Model is what defines the structure of our data and how it will be stored in the database. Django has a built-in Object Relational Mapper, or ORM, that you can use to easily put data into, and get data out of the database. A given Django application has a file, and this is where the Models for our application are defined. You can have one or many in the same file. In Django, a Model is a class that inherits from Django.db.models.Model. Models use class attributes to define their fields. We just want to add a few fields so that we can track the name, breed, and description of each Dog in our Django application.

from django.db import models

class Dog(models.Model):
    name = models.CharField(max_length=100)
    breed = models.CharField(max_length=30, blank=True)
    description = models.TextField()

Django Migrations

Django models define the expected structure of our database. Migrations are responsible for creating the necessary scripts to change this structure through time as a project evolves. In Django, when you add a Model to the file, the related database table does not yet exist. When a new model is created, an initial migration creates the database table. Migrations are also needed when a field is added or removed from an existing model, or when attributes of a field have changed. All of these changes to a file need a corresponding change to the database and for this purpose, a migration needs to be created and run. What is nice in Django is that you do not have to manually create the migration, it is generated by Django for you. The way this works is you have to define the Model yourself, then use the makemigrations command to generate migrations files. This command reads the current models file and inspects the current state of the database to determine what changes need to be made to make the database structure match the file. Migrations are needed in all of the following cases.
Django migrations needed for

With our Model defined above, we can now make our initial migration using the command python makemigrations. We should see output similar to below.

djangotutorial $python makemigrations
Migrations for 'djangodogs':
    - Create model Dog

There is now an a file named in the application, and the auto generated code from Django looks like so.

# Generated by Django 3.0

from django.db import migrations, models

class Migration(migrations.Migration):

    initial = True

    dependencies = [

    operations = [
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=100)),
                ('breed', models.CharField(blank=True, max_length=30)),
                ('description', models.TextField()),

Django itself has many migrations already built in and we can view the migrations using the python showmigrations command. This builds out the tables for things like the authentication system among others. The key piece of information to note from the output below is that we now have the 0001_initial migration that is a custom defined migration in the djangodogs application.

djangotutorial $python showmigrations
 [ ] 0001_initial
 [ ] 0002_logentry_remove_auto_add
 [ ] 0003_logentry_add_action_flag_choices
 [ ] 0001_initial
 [ ] 0002_alter_permission_name_max_length
 [ ] 0003_alter_user_email_max_length
 [ ] 0004_alter_user_username_opts
 [ ] 0005_alter_user_last_login_null
 [ ] 0006_require_contenttypes_0002
 [ ] 0007_alter_validators_add_error_messages
 [ ] 0008_alter_user_username_max_length
 [ ] 0009_alter_user_last_name_max_length
 [ ] 0010_alter_group_name_max_length
 [ ] 0011_update_proxy_permissions
 [ ] 0001_initial
 [ ] 0002_remove_content_type_name
 [ ] 0001_initial
 [ ] 0001_initial

Everything is now in place for us to run the migrations. We can do this using the python migrate command like so.

djangotutorial $python migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, djangodogs, 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 djangodogs.0001_initial... OK
  Applying sessions.0001_initial... OK

When we first ran the showmigrations command, we saw a [ ] at the beginning of each migration. This means that the migration exists, but has not yet been run. If there is a [x] to the left of each migration, that means the migration has been run. We can use the python showmigrations command one more time to display the migrations and verify that they have been run successfully.

djangotutorial $python showmigrations
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
 [X] 0010_alter_group_name_max_length
 [X] 0011_update_proxy_permissions
 [X] 0001_initial
 [X] 0002_remove_content_type_name
 [X] 0001_initial
 [X] 0001_initial

python shell

We can test our new Model out now. We need to use the shell via the python shell command. We can add our first dog to the system like so.

Insert Record Into Database

djangotutorial $python shell
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:21:23) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from djangodogs.models import Dog
>>> dog = Dog(name='Winnie', breed='Havanese', description='Fun loving female!')

Retrieve Record From Database

We did not get any errors when inserting our first record into the database using the Django ORM. To query the database using the ORM so we can view that record, we can use these commands.

>>> dogs = Dog.objects.all()
>>> dog = dogs[0]
>>> dog.breed
>>> dog.description
'Fun loving female!'

Once we add another record to the database, the .all() command returns more than one result.

>>> Dog.objects.all()
<QuerySet [<Dog: Dog object (1)>, <Dog: Dog object (2)>]>

URL -> View -> Model -> Template

We can put it all together now. When we visit the homepage, we want to display all Dogs. We should be able to click the dog name, and Django will load the detail template to show the details of each particular dog. This is the updated home() function in the file to list all Dogs.

from django.shortcuts import render
from .models import Dog
from django.http import Http404

def home(request):
    dogs = Dog.objects.all()
    return render(request, 'home.html', {'dogs': dogs})

The home.html template must also now be updated to allow us to loop over any number of dogs in the system. Django provides special tags in the templating language to allow for this.

<html lang="en-US">
    <meta charset="UTF-8">
    <title>Hello Doggies!</title>
{% for dog in dogs %}
    <a href="{% url 'dog_detail' %}">
        <h1>{{|capfirst }}</h1>
{% endfor %}

Visiting the homepage shows that we now see the small listing of Dogs in the system! Also notice that each dog is clickable, with the correct ID used in the href.

django home page listing all resources

To ensure the ability to click on each Dog works, we need to update the dog_detail() function in the file. Here is the updated code which now uses the ID provided to fetch a given Dog from the database using the Model we created.

from django.shortcuts import render
from .models import Dog
from django.http import Http404

def home(request):
    dogs = Dog.objects.all()
    return render(request, 'home.html', {'dogs': dogs})

def dog_detail(request, id):
    dog = Dog.objects.get(id=id)
    return render(request, 'dog_detail.html', {'dog': dog})

The last step now is to simply update the dog_detail.html template file to display the details of one particular dog.


<html lang="en-US">
    <meta charset="UTF-8">
    <title>Dog Detail!</title>
<h1>Dog with id of {{ }}</h1>
<h2>This dogs name is {{ }}</h2>
<h2>The breed of this dog is {{ dog.breed }}</h2>
<h2>Description: {{ dog.description }}</h2>

Our finished mini-application is working well 🙂

Learn More About Django

Django For Beginners Summary

If you made it all the way through this Django for beginners tutorial, congratulations! You are now on your way to putting the power of Python and Django to work for you in new and exciting ways. When choosing a Web Framework to work with, Django is the leading choice for Python web developers. In this tutorial, we covered a lot of ground including:

  • What Django Is
  • Getting Django Installed
  • Creating A Django Project
  • How To Create Django Apps
  • The Files of a Django App
  • Django Routing, Views, Models, and Templates
  • Configuring Your Django Homepage
  • URL Routing
  • Passing an ID via a Route
  • Passing Data To a Template From a View
  • Django Models
  • Django Migrations
  • Inserting Records Into the Database
  • Retrieving Records From the Database
  • Additional Resources For Django
Click to share! ⬇️