Django Basics: Models, Views, and Templates

· 5 min read · Updated March 16, 2026 · beginner
django web python backend mvc orm

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