DEV Community

Cover image for Django Tutorial #3: The MTV Structure
Eric Hu
Eric Hu

Posted on • Originally published at

Django Tutorial #3: The MTV Structure

You can download the source code of this tutorial here.

Introducing the MTV Structure

The MTV structure means that the application is divided into three parts. The (M) model defines the data model, (T) template presents data and (V) view defines logic and manipulates data.


Views act like the controllers in Laravel. It is the place where you organize the logic and the behaviour of your app. Views receive requests from URLs, retrieve data from the database through models, and finally return a template.

In Django, all the views are defined in the You can make it return a string like this:

from django.http import HttpResponse

def home(request):
    return HttpResponse("Hello, world. You're at the home page.")
Enter fullscreen mode Exit fullscreen mode

But, before you can see the string in your browser, edit the URL configurations like this:

from django.urls import path, include

urlpatterns = [
    path('', include('blog.urls'))
Enter fullscreen mode Exit fullscreen mode

If the URL is not followed by an argument, go to /blog/

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home),
Enter fullscreen mode Exit fullscreen mode

Again if the URL is not followed by an argument, go to the home view.

Start the server and go to This is what you should see:


We can also use the view to retrieve data from the database and put them in the template like this (assuming we have a Post model and a home template, we’ll talk about templates and models later):

from django.shortcuts import render
from .models import Post

def home(request):
    posts = Post.objects.all()

    return render(request, 'blog/home.html', {
        'posts': posts,
Enter fullscreen mode Exit fullscreen mode

In this example, the home view will get all the posts from the Post model, and render the data with the template called home.html, and eventually, return the rendered page.


Next, let’s talk about templates. For our project, the templates are all stored in the /templates directory, and you may have noticed that they are all HTML files. Yes, templates are based on HTML and CSS since they are what you see in the browser, but things are slightly more complicated than that.


If it contains only HTML codes, the entire website would be static, and that is not what we want. So the template would have to “tell” the view where to put the retrieved data.


The primary benefit of using the Django template is that we do not need to write the same code over and over again. Let’s create a master.html file in the templates folder. As the name suggests, this is the master of all other templates.

<!DOCTYPE html>
    {% block meta %} {% endblock %}

<div class="container">
    {% block content %} {% endblock %}
Enter fullscreen mode Exit fullscreen mode

In this file, two blocks are created, meta and content. To use this master layout, we define a home.html template.

{% extends 'master.html' %}

{% block meta %}
    <title>Page Title</title>
    <meta charset="UTF-8">
    <meta name="description" content="Free Web tutorials">
    <meta name="keywords" content="HTML, CSS, JavaScript">
    <meta name="author" content="John Doe">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
{% endblock %}

{% block content %}
<p>This is the content section.</p>
    {% include 'vendor/sidebar.html' %}
{% endblock %}
Enter fullscreen mode Exit fullscreen mode

When this template is used, Django will extend it to the master.html page, and fill out the meta and content blocks with information on this home.html page.

Also, notice there is something else in this template. {% include 'vendor/sidebar.html' %} tells Django to look for the /templates/vendor/sidebar.html and put it here.

<p>This is the sidebar.</p>
Enter fullscreen mode Exit fullscreen mode

It is not exactly a sidebar, but we can use it to prove this inheritance works. Make sure your home view is correct. We deleted the Post model and hardcoded a name variable which we will use later:

from django.shortcuts import render

def home(request):
    name = 'Eric'

    return render(request, 'blog/home.html', {
        'my_name': name,
Enter fullscreen mode Exit fullscreen mode

Also make sure your URL configuration points to this view. After that, start the server and go to



Display Data

Remember we have a variable sent to the home template? We can display this variable in the template like this:

<p>Hello, {{ my_name }}.</p>
Enter fullscreen mode Exit fullscreen mode

The out put will be Hello, Eric.


Tags provide arbitrary logic in the rendering process. The block that we talked about earlier is an example of a tag. Notice that they are all surrounded by {% and %}.

The most common tags include the for loop:

    {% for athlete in athlete_list %}
        <li>{{ }}</li>
    {% endfor %}
Enter fullscreen mode Exit fullscreen mode

And if statement:

{% if somevar == "x" %}
  This appears if variable somevar equals the string "x"
{% endif %}
Enter fullscreen mode Exit fullscreen mode

Here is a full list of all built-in tags in Django:


Filters transform the values of variables and tag arguments. For example, we have a variable django, with the value 'the web framework for perfectionists with deadlines'. If we put a title filter on this variable:

{{ django|title }}
Enter fullscreen mode Exit fullscreen mode

The template will render to:

The Web Framework For Perfectionists With Deadlines
Enter fullscreen mode Exit fullscreen mode

Here is a full list of all built-in filters in Django:


The model is one of the greatest features of Django. For a framework like Laravel, you need to create both a model and a migration file. The migration file is a schema for the database, it describes the structure (column names and column types) of the database. The model defines relations and handles the data retrieving based on that schema.

But for Django, you only need a model, and the corresponding migration files can be created with a simple command, which will save you a lot of time.

Generally, each model corresponds to a single table. Here is an example:

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
Enter fullscreen mode Exit fullscreen mode

This model will create a database table named myapp_person, and inside the table, there will be three columns each named id, first_name and last_name. The id column is created automatically.

CharField() is called a field type and it defines the type of the column. max_length is called a field option, and it specifies extra information about that column.

Models can be quite confusing for beginners, especially when it comes to complex relations, so we won’t go into details about these right now. Instead, we’ll talk about them with real examples later in the tutorial.

Fetching Data Using QuerySet

As an example, assuming we created the Person model. The following code will get the person whose id is 3:

from .models import Person

def home(request):
    person = Person.objects.filter(id=3)
Enter fullscreen mode Exit fullscreen mode

And we can also access the person’s first and last name with it. We will revisit this part in the future part of the tutorial.

Discussion (0)