0% completed
The Model-View-Template (MVT) Architecture
On This Page
The Model: Defining and Storing Data
The View: Handling the Request
The Template: Displaying the Data
How the Three Work Together
Three pieces of code take part in almost every page a Django site shows. One piece describes the data and how it is stored, one decides what to do with a request, and one decides how the result looks in the browser. Django calls them the model, the view, and the template, and the way it divides the work between them is the Model-View-Template (MVT) architecture.
Keeping the three apart means that each one can change without breaking the others. A designer can rework the HTML of a page without touching the database code, and a developer can change how articles are fetched without touching the HTML. This lesson builds one page of the blog, the list of all articles, and shows which part of the page each piece is responsible for.
The Model: Defining and Storing Data
A model is a Python class that describes one kind of record your application stores. Each model class becomes one table in the database, and each attribute of the class becomes a column. Django's ORM creates and manages these tables, so you work with Python objects instead of writing SQL.
The blog needs to store articles, and each article has a title, a body, an author, and a publication date. Add this model to the blog app:
# blog/models.py from django.db import models from django.utils import timezone class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() author = models.CharField(max_length=100) published_date = models.DateTimeField(default=timezone.now) def __str__(self): return self.title
CharField holds short text with a maximum length, and TextField holds text of any length, such as the article body. The published_date field takes the current date and time when an article is created, through default=timezone.now, but an editor can still change it later, for example to schedule an article. The __str__ method tells Django how to show an article as text, such as in the admin site or the shell.
Django names the table after the app and the model, in lowercase, so this model is stored in a table called blog_article. Django also adds an id column that numbers each row automatically. You do not create the table yourself: the makemigrations and migrate commands generate and run the SQL for it, as Chapter 2 explains. For reference, this is the table Django creates on SQLite:
CREATE TABLE "blog_article" ( "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(200) NOT NULL, "content" text NOT NULL, "author" varchar(100) NOT NULL, "published_date" datetime NOT NULL );
Once the table exists, you can add, read, change, and delete articles with Python code such as Article.objects.all(), without writing SQL.
The View: Handling the Request
A view is a Python function, or a class, that receives a request and returns a response. Between those two steps, it does whatever work the page needs: it reads data through the models, makes decisions, and hands the results to a template.
The article list page needs all articles from the database. This view fetches them and passes them to a template:
# blog/views.py from django.shortcuts import render from .models import Article def article_list(request): articles = Article.objects.all() return render(request, 'blog/article_list.html', {'articles': articles})
Every view receives the request as its first argument. The render function loads the template named in the second argument, fills it with the values in the dictionary, which is called the context, and returns the finished HTML page as a response. Inside the template, the name articles now refers to the articles the view fetched.
The view does not know how the page looks, and the model does not know that a page exists. That separation is the point of the architecture.
The Template: Displaying the Data
A template is a text file, usually HTML, that contains placeholders and simple instructions for Django. Django replaces {{ name }} with the value of name from the context, and it runs tags such as {% for %} to repeat a block of HTML for each item in a list.
Django looks for templates in a folder named templates inside each installed app. Create the file blog/templates/blog/article_list.html. The extra blog folder inside templates keeps this file apart from templates with the same name in other apps.
<!DOCTYPE html> <html> <head> <title>Blog Articles</title> </head> <body> <h1>All Articles</h1> <ul> {% for article in articles %} <li> <h2>{{ article.title }}</h2> <p>By {{ article.author }} on {{ article.published_date }}</p> <p>{{ article.content }}</p> </li> {% endfor %} </ul> </body> </html>
With one article in the database, titled "Hello Django" and written by Ana, the list part of the page renders like this:
<h1>All Articles</h1> <ul> <li> <h2>Hello Django</h2> <p>By Ana on March 2, 2026, 9 a.m.</p> <p>First post.</p> </li> </ul>
The template contains no database code. Because the view runs the query again on every request, a newly added article appears the next time someone loads the page, and nobody has to edit the template.
How the Three Work Together
One more piece is needed before a browser can reach this page: a URL pattern that connects an address such as /articles/ to the article_list view. Django's URL dispatcher reads the requested address and picks the view, and the next lesson shows how to set it up. With that in place, a request for the article list goes through these steps:
- The browser asks for
/articles/. - The URL dispatcher matches the address and calls the
article_listview. - The view asks the
Articlemodel for all articles, and the model reads them from theblog_articletable. - The view passes the articles to the
blog/article_list.htmltemplate, and the template turns them into HTML. - Django sends the HTML back to the browser as the response.
The diagram below shows the same flow. Follow the arrows from the client's request, through the URL dispatcher to the view, out to the model and the database, and back to the view with the articles. Then notice that the view hands the data to the template and receives the rendered HTML back, and that the view, not the template, returns the page to the client.
If you know the Model-View-Controller (MVC) pattern from other frameworks, the names can mislead you. In Django, the view decides which data is shown, which is the job MVC gives to the controller, while the template decides how it is shown, which is the job MVC gives to the view. The framework itself, through the URL dispatcher, does the rest of the controller's work.
Reading Progress
0%
On This Page
The Model: Defining and Storing Data
The View: Handling the Request
The Template: Displaying the Data
How the Three Work Together