Django Basics: Models, Views, and Templates
Django is a high-level Python web framework that includes everything you need to build web applications. It follows the “batteries included” philosophy, providing authentication, admin interface, database ORM, and form handling out of the box.
This tutorial covers creating a Django project, defining models, writing views, and rendering templates. By the end, you will have a working Django application.
Installing Django
Django installs via pip. Create a virtual environment first.
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install django
Verify the installation.
django-admin --version
Creating a Django Project
Use the django-admin command to create a new project. This sets up the directory structure and configuration files.
django-admin startproject myproject
cd myproject
Here is what the project structure looks like:
myproject/
├── manage.py
└── myproject/
├── __init__.py
├── settings.py
├── urls.py
├── asgi.py
└── wsgi.py
The outer myproject/ is the project root. The inner myproject/ contains the Python package. manage.py is the command-line utility for running Django commands.
Run the development server.
python manage.py runserver
Visit http://127.0.0.1:8000 in your browser. You should see the Django welcome page.
Creating a Django App
Django projects contain one or more apps. An app is a web application that does something. Create an app for a simple blog.
python manage.py startapp blog
Your structure now includes the blog/ directory:
blog/
├── __init__.py
├── admin.py
├── apps.py
├── migrations/
├── models.py
├── tests.py
└── views.py
Open myproject/settings.py and add blog to the INSTALLED_APPS list.
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"blog",
]
Defining Models
Models define your database schema. Each model is a Python class that inherits from django.db.models.Model.
Open blog/models.py and create a simple Post model.
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
Each field in the model maps to a database column. CharField is for short text, TextField is for long text, and DateTimeField stores timestamps.
Create the database tables.
python manage.py makemigrations
python manage.py migrate
The first command creates migration files describing the schema changes. The second command applies those changes to the database. SQLite is the default database, so no additional setup is required.
Creating the Admin Interface
Django provides an automatic admin interface for managing your models. Register your model in blog/admin.py.
from django.contrib import admin
from .models import Post
admin.site.register(Post)
Create a superuser to log in.
python manage.py createsuperuser
Follow the prompts to set a username, email, and password.
Run the server and visit http://127.0.0.1:8000/admin. Log in with your superuser credentials. You can now create, edit, and delete posts through the admin interface.
Writing Views
Views handle the logic for your web pages. Each view is a Python function (or class-based view) that receives a web request and returns a response.
Open blog/views.py and create views for listing and showing posts.
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
posts = Post.objects.all().order_by("-created_at")
return render(request, "blog/post_list.html", {"posts": posts})
def post_detail(request, post_id):
post = get_object_or_404(Post, id=post_id)
return render(request, "blog/post_detail.html", {"post": post})
The render function combines a template with context data to produce an HTML response. get_object_or_404 retrieves an object or returns a 404 error if not found.
Creating Templates
Templates define the HTML structure of your pages. Django looks for templates in a templates directory within each app.
Create the template directories and files.
mkdir -p blog/templates/blog
touch blog/templates/blog/post_list.html
touch blog/templates/blog/post_detail.html
Create blog/templates/blog/post_list.html:
<!DOCTYPE html>
<html>
<head>
<title>Blog</title>
</head>
<body>
<h1>My Blog</h1>
{% for post in posts %}
<article>
<h2><a href="{% url post_detail post.id %}">{{ post.title }}</a></h2>
<p>{{ post.created_at|date:"F j, Y" }}</p>
<p>{{ post.content|truncatewords:30 }}</p>
</article>
{% empty %}
<p>No posts yet.</p>
{% endfor %}
</body>
</html>
Django templates use template tags like {% for %} and template filters like |truncatewords:30. The {% url %} tag generates URLs by name.
Create blog/templates/blog/post_detail.html:
<!DOCTYPE html>
<html>
<head>
<title>{{ post.title }}</title>
</head>
<body>
<h1>{{ post.title }}</h1>
<p>Published {{ post.created_at|date:"F j, Y" }}</p>
<div>
{{ post.content|linebreaks }}
</div>
<p><a href="{% url post_list %}">Back to list</a></p>
</body>
</html>
Configuring URLs
URL configuration maps URLs to views. Create blog/urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.post_list, name="post_list"),
path("post/<int:post_id>/", views.post_detail, name="post_detail"),
]
Include these URLs in the project-level myproject/urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("blog.urls")),
]
The include function delegates URL matching to the app-level configuration.
Testing Your Application
Run the development server.
python manage.py runserver
Visit http://127.0.0.1:8000. You should see the post list. Since you have no posts yet, log in at /admin and create some posts through the admin interface. Then return to the list page to see them displayed.
Click on a post title to view the detail page.
Conclusion
You created a Django project, defined a model with fields and timestamps, registered it with the admin interface, wrote views to handle requests, and created templates to render HTML. These components form the foundation of every Django application.
The next tutorial in this series covers authentication with FastAPI. For now, explore the Django documentation to learn about forms, class-based views, and the testing framework.
See Also
See Also
- Flask Basics: Your First Web App — The first tutorial in this series, covering Flask fundamentals
datetime— Learn about datetime handling in Python- Working with APIs — Learn how to consume APIs in Python