Django Tutorial #3: The MTV Structure

Django Tutorial #3: The MTV Structure

Please note that this post may contain affiliate links, and for every purchase you make, at no extra cost to you, a commission fee will be rewarded to me.

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

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 views.py. You can make it return a string like this:

blog/views.py

from django.http import HttpResponse


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

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

Django_31_Tutorial/urls.py

from django.urls import path, include

urlpatterns = [
    path('', include('blog.urls'))
]

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

blog/urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home),
]

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

Start the server and go to http://127.0.0.1:8000/. 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,
    })

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.

Templates

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.

Inheritance

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>
<html>
<head>
    {% block meta %} {% endblock %}
</head>
<body>

<div class="container">
    {% block content %} {% endblock %}
</div>
</body>
</html>

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 %}

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.

sidebar.html

<p>This is the sidebar.</p>

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,
    })

Also make sure your URL configuration points to this view. After that, start the server and go to http://127.0.0.1:8000/

Syntax

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>

The out put will be Hello, Eric.

Tags

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:

<ul>
    {% for athlete in athlete_list %}
        <li>{{ athlete.name }}</li>
    {% endfor %}
</ul>

And if statement:

{% if somevar == "x" %}
  This appears if variable somevar equals the string "x"
{% endif %}

Here is a full list of all built-in tags in Django: https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#ref-templates-builtins-tags

Filters

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 }}

The template will render to:

The Web Framework For Perfectionists With Deadlines

Here is a full list of all built-in filters in Django: https://docs.djangoproject.com/en/3.1/ref/templates/builtins/#ref-templates-builtins-filters

Models

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)

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:

blog/views.py

from .models import Person

def home(request):
    person = Person.objects.filter(id=3)

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.

Leave a Reply

Your email address will not be published. Required fields are marked *