Django Unleashed: Building Your First Web App Step by Step

Sam Fredrick
DataX Journal
Published in
11 min readNov 17, 2023

Before we dive into the world of Django, it’s crucial to understand why this powerful web framework is a game changer . Django provides a robust foundation for crafting server-side applications with remarkable efficiency. It has a pre built set of structured libraries, tools and guidelines which developers can use to build applications. Additionally, it offers reusable code which and design patterns which simplifies the development process as we don’t have to code everything from scratch.

In this blog we are going to explore the inner workings of Django and embark on a journey to create a simple blogging site. So lets begin this adventure into the fascinating world of Django.

Django Architecture

Django follows Model-View-Template (MVT) architecture which is similar to commonly used Model-View-Controller (MVC) architecture. Here is a description of each component:

Model: Django’s Model is in charge of managing and accessing database data. It establishes the data’s structure and manages all database operations, including data manipulation and querying.

Views: Views are functions defined to determine what happens to when a web request is sent to the backend. They interact with the model to retrieve or store data from the request and return a response.

Template: Template contains the user interface which is rendered in the browser of the user and it contains static code written in HTML, CSS and JS. It works with views to receive data and represents them in a readable format in the webpage.

In addition to these components, URL routing is a fundamental part of Django’s architecture. It maps URLs to the appropriate Views, allowing users to interact with your web application.

Getting Started

Now that we have covered the basic concepts lets get into coding and understand more concepts along the way.

To work with Django we must have it installed. It is recommended that you do the installation of Django at a virtual environment. To install Django run the following command in shell:

pip install Django

To verify the installation of Django and to check the version of it you can use this command:

python -m django --version

To create a web application you must create a project in Django which can be done by this command:

django-admin startproject myproject

Once the project is created, you’ll find some Python files and directories in a structure like this:

myproject/
|-- manage.py
|-- myproject/
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- asgi.py
| |-- wsgi.py

Now lets understand what each file does:

manage.py — a command-line utility that lets you interact with your Django project in many ways. It is similar to django-admin but specific to this project.

__init__.py — This file is used to let Python know to treat this package.

settings.py — Contains setting config which are specific to this project.

urls.py — Contains URL patterns for this project.

asgi.py — Serves as the entry point for ASGI servers.

wsgi.py — Acts as an application entry point when the project is moved into production.

Now that we have created a project, let’s run the server and see it in action. Ensure that you are in the same directory as manage.py and run the following command:

python manage.py runserver

Don’t worry about any migration errors, we can ignore them as of now. Now, go to this URL http://127.0.0.1:8000/ and you’ll see this default page.

Hello world

Now lets dive into creating apps in Django. In Django, “app” is a self contained module which has set of related functionalities designed to work with a larger Django project. So a Django project can have many apps, serving its own purpose and these can be individually disconnected and used in other Django projects.

To create an app again ensure you’re in the same directory of manage.py and execute this following command:

python manage.py startapp blog

This command will create a new app named “blog” in our project, and now the project structure will resemble the following:

myproject/
|-- manage.py
|-- myproject/
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| |-- asgi.py
| |-- wsgi.py
|-- blog/
| |-- __init__.py
| |-- admin.py
| |-- apps.py
| |-- migrations/
| | |-- __init__.py
| |-- models.py
| |-- tests.py
| |-- views.py

Now lets understand what each file does:

__init__.py — This file is used to let Python know to treat this package.

admin.py — This is used to configure admin interface of your app.

apps.py — Contains setting config for this app.

migrations/ — This directory stores the migration files of this app. When changes are made to app’s models, Django keeps track of the changes made to the database.

models.py — This is where we define the app’s data models.

test.py — This file is used to writing tests for the app.

views.py — This file is where you define the views or functions that handle HTTP requests and generate responses.

Now, let’s create our first “Hello World” program. First, open settings.py in the project directory and search the INSTALLED_APPS list and add our new app to it.

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

'blog',
]

Open views.py in your app directory using a text editor and add the following code:

from django.http import HttpResponse

def hello_world(request):
return HttpResponse("Hello, World!")

This code accepts a HTTP request and responds with a HTTP response saying Hello, World

Now create a new file named urls.py in same directory to contain all the URL routing specific to this app and paste this code inside.

from django.urls import path
from . import views

urlpatterns = [
path('',views.hello_world ),
]

This code defines a URL routing so when a request is made to an empty string it will call the hello_world view defined in views.py.

Finally, open the urls.py in the project directory and modify the code into this:

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
path('admin/', admin.site.urls),
path('',include('blog.urls'))

]

This updated code instructs the Django project to include the URL routing defined in the “blog” app.

Now, let’s test our “Hello, World!” program. Run the development server again and go the same URL as before and you can see the Hello, World! response.

Congratulations on successfully creating your “Hello, World!” program.

Blog site

Now , start creating the blog application. First we’ll design the database model. Before that, we need to determine the fields required for our application. Open models.py, and let's create a new model.

from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.contrib.auth.models import User

from django.urls import reverse

class Post(models.Model):
title = models.CharField(max_length=250, unique=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts')
content = models.TextField()
publish_time = models.DateTimeField(default=timezone.now)

class Meta:
ordering = ('-publish_time',)

def __str__(self):
return self.title

def get_absolute_url(self):
return reverse('blog:blog_detail', args=[str(self.id)])

Here is a short explanation of the fields used in the Post

title: Used to store the title of the blog post. It is a character field and has the maximum length of 250 characters.

author: A foreign key to the built-in User model in Django, indicating the author of the blog post. It's set to cascade deletion, meaning when a user is deleted, all their associated blog posts will also be deleted.

content: A text field where the blog post’s content is stored.

publish_date: A DateTime field with the current time as its default value. This keeps track of the time and date that the blog was created.

It is now time to migrate our application to the database as we have finished designing the model. Executing the following commands will accomplish this:

python manage.py makemigrations
python manage.py migrate

By default, Django uses db.sqlite as the database, and these commands apply the changes to set up the database for your blog application.

Now let’s create a admin user to access the admin site of Django also, they are known as superusers, have permission to create, edit and delete content from the admin panel. To create a super user use the following command and use any credentials you prefer.

python manage.py createsuperuser
Username (leave blank to use 'sam'): admin
Email address: admin@admin.com
Password:*****
Password (again):****
Superuser created successfully.

To enable the admin user to access and manage the Post model, we have to register it in the admin panel. To do this, open admin.py add the following code.

from django.contrib import admin
from .models import Post

admin.site.register(Post)

With the Post model registered, now you can go to the admin site by this URL http://127.0.0.1:8000/admin/ . login and add a some blog post so we can work on displaying them.

While working on views now we will be using a class based views for the displaying the posts. Since we don’t have to write everything from start, class-based views are more advantageous than function-based views. Because of this, adopting class-based views will save us time and make the code easier to understand.

Now modify views.py to create two class based views, one to list and one show the full details of the blog.

from django.views.generic import ListView, DetailView
from .models import Post


class BlogListView(ListView):
model = Post
context_object_name = 'posts'
template_name = 'blog/list.html'


class BlogDetailView(DetailView):
model = Post
context_object_name = 'post'
template_name = 'blog/detail.html'

To display a list of all blog entries, we used BlogListView in this code. It inherits from ListView, a generic Django view for showing lists of objects. We also have a class called BlogDetailView that shows all the information about a particular blog. The model to use is also specified; in this case, it is Post. The template to utilize to render the information on the webpage has also been provided.

Now, let’s start creating templates for our blog application. Templates in Django are used to define the structure and layout of web pages. In your app directory create a new folder named templates . Inside that make a another directory named blog. This will store all the templates of this app. Create a new file named base.htmland add the following code. This will serve as the base template for our site. Feel free to change the style and the structure of the frontend:

<!DOCTYPE html>
<html>
<head>
<title>My Blog</title>
<style>
body, h1, h2, h3, p {
margin: 0;
padding: 0;
}
body {
font-family: 'Arial', sans-serif;
background-color: #f8f8f8;
color: #333;
}
header {
background-color: #333;
color: #fff;
text-align: center;
padding: 20px;
font-size: 24px;
text-transform: uppercase;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.2);
}
nav ul {
list-style: none;
text-align: center;
background-color: #333;
margin-top: 20px;
}
nav ul li {
display: inline;
margin-right: 20px;
}
nav ul li a {
color: #fff;
text-decoration: none;
font-size: 16px;
transition: color 0.3s;
}
nav ul li a:hover {
color: #f0f0f0;
}
main {
max-width: 800px;
margin: 20px auto;
background-color: #fff;
padding: 20px;
border-radius: 10px;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}
h2 {
color: #333;
font-size: 24px;
margin-bottom: 10px;
}
ul {
list-style: none;
}
ul li {
margin-bottom: 20px;
border-bottom: 1px solid #e0e0e0;
padding-bottom: 10px;
}
ul li:last-child {
border-bottom: none;
margin-bottom: 0;
}
footer {
text-align: center;
background-color: #333;
color: #fff;
padding: 10px;
}
a {
color: #337ab7;
text-decoration: none;
transition: color 0.3s;
}
a:hover {
color: #23527c;
}
</style>
</head>
<body>
<header>
<h1>My Blog</h1>
</header>
<nav>
<ul>
<li><a href="{% url 'blog:blog_list' %}">Home</a></li>
</ul>
</nav>
<main>
{% block content %}
{% endblock %}
</main>
<footer>
&copy; My Blog
</footer>
</body>
</html>

The header, navigation, primary content, and footer of the webpage are all defined by this code. A placeholder for dynamic material using Django template tags is also included. Create another file named list.html within the blog directory and add the following code:

{% extends 'blog/base.html' %}

{% block content %}
<h2>Blog Posts</h2>
<ul>
{% for post in posts %}
<li><a href="{% url 'blog:blog_detail' post.id %}">{{ post.title }}</a></li>
{% endfor %}
</ul>
{% endblock %}

The list.html template extends the base.html template and includes content specific to displaying a list of blog posts. Create a file named detail.html within the blog directory and add the following code:

{% extends 'blog/base.html' %}

{% block content %}
<h2>{{ post.title }}</h2>
<p>Author: {{ post.author }}</p>
<p>Published on: {{ post.publish_time }}</p>
<p>{{ post.content }}</p>
<a href="{% url 'blog:blog_list' %}">Back to Blog</a>
{% endblock %}

The detail.html template extends the base.html template and includes content specific to displaying the details of a single blog post.

You’ll see two different types of template tags in the provided code: {{ }} and {% %}. The template variable, denoted by the double curly braces, {{ }}, is used to output dynamic data, such as the {{ post.title }} variable, which displays the title of a blog post. On the other hand, template tags, denoted by curly braces and percentage marks, {% %}, are used for control flow and logic within the template. For instance, the statement {% extends 'blog/base.html' %} indicates that the template extends the structure described in 'blog/base.html', and the statement {% for post in posts %} is a loop that iterates through a list of blog entries. Django templates are fundamentally made up of template tags and variables that allow you to build reusable templates for your web pages and insert dynamic content.

Finally go to urls.py, and modify the code.

from django.urls import path
from .views import BlogListView, BlogDetailView

app_name = 'blog'

urlpatterns = [
path('', BlogListView.as_view(), name='blog_list'),
path('<int:pk>/', BlogDetailView.as_view(), name='blog_detail'),
]

We are setting up URL routing for our blog application in the code above. Using app_namewe have also created a new namespace for our application. When you have numerous apps with similar URL patterns, this Django recommended practice helps you prevent problems. The URL for showing a list of blog entries is specified by this path. The root URL for the blog app is represented by the empty string (‘’) in the first pattern. When a user accesses this URL, the class-based BlogListView view is activated and shows the list of posts. For convenience, we provide the name “blog_list” to this URL pattern.

The specifics of a single blog post are shown via the second path. The <int:pk> is a dynamic part of the URL, which represents the primary key of the post. . The BlogDetailView view is launched when a user hits a URL like “/blog/1/,” which displays the specifics of the article with ID 1. We also assign the name 'blog_detail' to this URL pattern.

With these URL patterns defined, your Django project knows how to route incoming requests to the appropriate views within your blog application. This configuration sets the foundation for users to access and interact with your blog’s list and post detail pages.

Conclusion:

Congratulations for finishing the process of building a Django blog site! You’ve come across a number of Django concepts and approaches during this journey. Keep in mind that you don’t have to learn everything at once. These concepts will flow naturally as you do more projects and gain experience. Now, the options are endless! Feel free to improve your application through integrating additional features or learning advanced Django topics. Don’t hesitate to embark on more projects and broaden your knowledge of Django web development. Happy coding!

--

--