In this lesson, we will bring together the major Django concepts learned throughout this tutorial and design a complete website project.
A complete Django website can contain a homepage, about page, contact page, authentication, database models, forms, search, pagination, an admin panel, and other application-specific features.
A complete Django website combines multiple Django components into one working application.
A typical website may contain:
Before writing code, plan the website structure.
For example, an education website could contain:
Home
About
Courses
Students
Blog
Contact
Login
Register
Admin
Planning helps keep the project organized.
Create the main Django project:
django-admin startproject mywebsite
Move into the project directory:
cd mywebsite
Run the development server:
python manage.py runserver
Create an application for the website's main functionality.
python manage.py startapp main
Add the app to INSTALLED_APPS.
INSTALLED_APPS = [
...
"main",
]
mywebsite/
│
├── manage.py
│
├── mywebsite/
│ ├── settings.py
│ ├── urls.py
│ ├── asgi.py
│ └── wsgi.py
│
└── main/
├── migrations/
├── templates/
│ └── main/
├── static/
├── __init__.py
├── admin.py
├── apps.py
├── models.py
├── forms.py
├── urls.py
├── views.py
└── tests.py
Create a homepage view in main/views.py.
from django.shortcuts import render
def home(request):
return render(
request,
"main/home.html"
)
def about(request):
return render(
request,
"main/about.html"
)
The view simply renders the About template.
def contact(request):
return render(
request,
"main/contact.html"
)
The Contact page can later be connected to a contact form and database model.
Create main/urls.py.
from django.urls import path
from . import views
urlpatterns = [
path(
"",
views.home,
name="home"
),
path(
"about/",
views.about,
name="about"
),
path(
"contact/",
views.contact,
name="contact"
),
]
Connect the application URLs to the main project.
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path(
"admin/",
admin.site.urls
),
path(
"",
include("main.urls")
),
]
Create a templates directory for the main application.
main/
└── templates/
└── main/
├── home.html
├── about.html
└── contact.html
Django will render these HTML files through the views.
A base template can contain common website elements such as the header, navigation, and footer.
<!DOCTYPE html>
<html>
<head>
<title>
{% block title %}
My Website
{% endblock %}
</title>
</head>
<body>
<nav>
<a href="{% url 'home' %}">
Home
</a>
<a href="{% url 'about' %}">
About
</a>
<a href="{% url 'contact' %}">
Contact
</a>
</nav>
{% block content %}
{% endblock %}
</body>
</html>
Child templates can extend the base template.
{% extends "main/base.html" %}
{% block title %}
Home
{% endblock %}
{% block content %}
<h1>
Welcome to My Website
</h1>
{% endblock %}
This prevents repeating common HTML across every page.
Static files include CSS, JavaScript, and images.
A common structure is:
main/
└── static/
└── main/
├── css/
│ └── style.css
├── js/
│ └── script.js
└── images/
In templates:
{% load static %}
<link
rel="stylesheet"
href="{% static 'main/css/style.css' %}"
>
Suppose the website needs a Course model.
from django.db import models
class Course(models.Model):
name = models.CharField(
max_length=150
)
description = models.TextField()
fee = models.DecimalField(
max_digits=10,
decimal_places=2
)
duration = models.CharField(
max_length=100
)
def __str__(self):
return self.name
Create and apply migrations after adding the model.
python manage.py makemigrations
python manage.py migrate
The database table for the Course model will be created.
The homepage can retrieve courses from the database.
from .models import Course
def home(request):
courses = Course.objects.all()
return render(
request,
"main/home.html",
{
"courses": courses
}
)
{% for course in courses %}
<div>
<h2>
{{ course.name }}
</h2>
<p>
{{ course.description }}
</p>
<p>
Fee:
{{ course.fee }}
</p>
<p>
Duration:
{{ course.duration }}
</p>
</div>
{% empty %}
<p>
No courses available.
</p>
{% endfor %}
A contact form can save visitor messages in the database.
class Contact(models.Model):
name = models.CharField(
max_length=100
)
email = models.EmailField()
subject = models.CharField(
max_length=200
)
message = models.TextField()
created_at = models.DateTimeField(
auto_now_add=True
)
def __str__(self):
return self.name
A ModelForm can be used for the Contact model.
from django import forms
from .models import Contact
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = [
"name",
"email",
"subject",
"message"
]
from django.shortcuts import render, redirect
def contact(request):
if request.method == "POST":
form = ContactForm(
request.POST
)
if form.is_valid():
form.save()
return redirect(
"contact"
)
else:
form = ContactForm()
return render(
request,
"main/contact.html",
{
"form": form
}
)
A complete website can include registration, login, logout, and protected pages.
from django.contrib.auth.decorators import login_required
@login_required
def dashboard(request):
return render(
request,
"main/dashboard.html"
)
Only authenticated users can access the protected view.
Search allows visitors to find database records quickly.
query = request.GET.get(
"q",
""
).strip()
courses = Course.objects.all()
if query:
courses = courses.filter(
name__icontains=query
)
The search can be displayed on a course listing page.
Pagination can divide a large list into smaller pages.
from django.core.paginator import Paginator
paginator = Paginator(
courses,
10
)
page_number = request.GET.get(
"page"
)
page_obj = paginator.get_page(
page_number
)
The template can display the current page of courses.
The Django admin panel provides an interface for managing database records.
from django.contrib import admin
from .models import Course, Contact
admin.site.register(
Course
)
admin.site.register(
Contact
)
Create an administrator account with:
python manage.py createsuperuser
A complete Django website can also provide REST API endpoints for mobile applications or JavaScript clients.
pip install djangorestframework
A serializer can convert model data into API-friendly representations.
from rest_framework import serializers
class CourseSerializer(
serializers.ModelSerializer
):
class Meta:
model = Course
fields = "__all__"
Before deploying a Django website, review the project's production settings and configuration.
DEBUG = False.ALLOWED_HOSTS.SECRET_KEY secure.python manage.py check --deploy
User
↓
Browser
↓
Django URL
↓
View
↓
Form / Model / ORM
↓
Database
↓
View
↓
Template
↓
HTML Response
↓
Browser
API Client
↓
Django API URL
↓
APIView / ViewSet
↓
Serializer
↓
Database
↓
JSON Response
↓
API Client
mywebsite/
│
├── manage.py
│
├── mywebsite/
│ ├── settings.py
│ ├── urls.py
│ ├── asgi.py
│ └── wsgi.py
│
└── main/
├── migrations/
├── templates/
│ └── main/
│ ├── base.html
│ ├── home.html
│ ├── about.html
│ ├── contact.html
│ ├── login.html
│ └── dashboard.html
│
├── static/
│ └── main/
│ ├── css/
│ ├── js/
│ └── images/
│
├── __init__.py
├── admin.py
├── apps.py
├── forms.py
├── models.py
├── urls.py
├── views.py
└── tests.py
A complete Django website combines the major concepts learned throughout the tutorial into one practical application.
Question: Which Django component is primarily responsible for processing a request and returning a response?