In the previous lesson I explained what Django does and why it was created. In this lesson we’ll cover how all the various parts of Django come together to create a website.
This lesson is about the big picture.
It can be hard to get started with Django because it’s such a huge project, but if you take the time to understand how all parts come together at a high level, you’ll master Django much quicker.
At the highest level, Django is a Model-View-Controller – or MVC – framework.
MVC is a software design pattern that aims to separate a web application into three interconnecting parts:
- The model, which provides the interface with the database containing the application data;
- The view, which decides what information to present to the user and collects information from the user; and
- The controller, which manages the business logic for the application and acts as an information broker between the model and the view.
Django uses slightly different terminology in its implementation of MVC (Figure 1). In Django:
- The model is functionally the same. Django’s Object-Relational Mapping (ORM—more on the ORM later) provides the interface to the application database;
- The template provides display logic and is the interface between the user and your Django application; and
- The view manages the bulk of the applications data processing, application logic and messaging.

Figure 1. A pictorial description of the Model-Template-View (MTV) pattern in Django.
The MVC design pattern has been used for both desktop and web applications for many years, so there are a large number of variations on this theme—of which Django is no exception. If you wish to dig a bit deeper into the MVC design pattern, just be warned that people can be quite passionate about what is a different interpretation of the same thing. To borrow a quote from the Django development team:
“At the end of the day, of course, it comes down to getting stuff done. And, regardless of how things are named, Django gets stuff done in a way that’s most logical to us.”
I whole-heartedly agree.
Django Models
Django’s models provide an Object-relational Mapping (ORM) to the underlying database. ORM is a powerful programming technique that makes working with data and relational databases much easier.
Most common databases are programmed with some form of Structured Query Language (SQL), however each database implements SQL in its own way. SQL can be quite complex and difficult to learn. An ORM tool on the other hand, provides a simple mapping between an object (the ‘O’ in ORM) and the underlying database, without the programmer needing to know the database structure, or requiring complex SQL to manipulate and retrieve data (Figure 2).

Figure 2. An ORM allows for simple manipulation of data without having to write complex SQL.
In Django, the model is the object that is mapped to the database. When you create a model, Django creates a corresponding table in the database (Figure 3), without you having to write a single line of SQL. Django prefixes the table name with the name of your Django application (more on Django applications later).

Figure 3. Creating a Django model, creates a corresponding table in the database.
The model also links related information in the database. In Figure 4, a second model is created to keep track of the courses a user is enrolled in. Repeating all the users information in the yourapp_Course
table would be against good design principles, so we instead create a relationship (the ‘R’ in ORM) between the yourapp_Course
table and the yourapp_UserProfile
table.

Figure 4. Relationships between tables are created by foreign key links in Django models.
This relationship is created by linking the models with a foreign key—in other words the user_id
field in our yourapp_Course
table is a key field that is linked to the id
field in the foreign table yourapp_UserProfile
.
This is a bit of a simplification, but is a handy overview of how Django’s ORM uses the model data to create database tables. We will be revisiting models a few times throughout the book, so don’t worry if you don’t 100% understand what is going on right now. Things become clearer once you have had the chance to build real models.
Supported Databases
Django 3.0+ officially supports five databases:
- PostgreSQL
- MySQL
- MariaDB
- SQLite
- Oracle
There are also a number of third party applications for connecting to other databases, if you need to connect to an unofficially supported database.
The preference for most Django developers, myself included, is PostgreSQL. MySQL is also a fairly common database backend for Django. Installing and configuring a database is not a task for a beginner— luckily, Django installs and configures SQLite automatically, with no input from you, so we will be using SQLite throughout this book.
Which Database is Better?
Easy one first—SQLite is for early development and testing. It should not be used in production. Ever.
Next easiest answer—Oracle is for big corporations with deep pockets. You are unlikely to need to decide whether to use Oracle unless you join a big enterprise, and then you might find it’s your only choice.
As for PostgreSQL, MariaDB and MySQL —There are definite reasons why PostgreSQL is a better database than MySQL. However, by the time you have learned enough programming to understand why, you will be in a position to judge for yourself. Most often the choice will have been made for you by the client, your employer or the web host.
Smart programmers avoid these kind of arguments—Use PostgreSQL if you can, otherwise MySQL and MariaDB are fine too.
MariaDB support was added with the release of Django 3.0. Given that it is a direct port of MySQL, using MariaDB with Django is identical to using MySQL with Django (they even use the same connector).
Django Templates
A Django template is a text file designed to separate an application’s data from the way it is presented. In most cases, Django templates are Hypertext Markup Language (HTML) files for presenting application data in a web browser, however Django templates are not limited to HTML—they can be used for rendering several different text formats.
The design of Django’s templates is based on several core principles, however three are key:
- A template system should separate program logic from design.
- Templates should discourage redundancy—Don’t Repeat Yourself (DRY).
- The template system should be safe and secure—code execution in the template must be forbidden.
Separate Logic From Design
Web design and web programming are two very different disciplines. For all but the smallest projects, design and programming are not done by the same people; in many cases, not even the same company.
When Django’s creators first considered the design of Django’s template system it was clear that Django programmers and website designers must be able to work independently of each other. The result is a plain-text scripting language that uses tags to provide presentation logic for deciding what content to display in the template. This is easier to understand with a simple example:
<h1>Your Order Information</h1>
<p>Dear {{ person_name }}
,</p>
This could be the first couple of lines of an order confirmation page, displayed on a website after the user has made a purchase. You will notice that the majority of this code is plain HTML. The small bit of script in bold is a Django variable tag. When this template is rendered in your browser, the template will replace the variable person_name
with the name passed to the template by the view.
As this is plain-text and HTML, a designer does not need to know anything about Django to be able to create a Django template. All the designer has to do is add a placeholder (HTML comment tag, for example), for the programmer to replace with a Django tag when coding the website.
The other major advantage of this approach is that, given the bulk of the template is plain HTML, you as a programmer, can create a good looking website without a designer—you can download a HTML template from the Internet and add Django template tags. This also works with Bootstrap templates and sites heavy in front-end JavaScript.
Don’t Repeat Yourself (DRY)
DRY is a term that comes up often in Django discussions as it’s one of Django’s core principles. The DRY principle is particularly evident in how Django uses template inheritance. To better understand how template inheritance helps us to minimize repetition and redundant code, let’s first examine a typical web page layout (Figure 5).

Figure 5. A typical webpage layout with common elements like a header, footer and navigation.
This page layout has a top navigation, a header image, left side menu, the main content of the page and a footer. If you only wanted to create a few web pages, you could get away with copying the front page and simply changing the content and saving each different page as a HTML file.
Problem is, not only are we repeating a lot of code, but maintaining a large site could quickly get out of hand—what if you needed to change the template? You would have to make the change on every single page in your site!
We fix this problem by creating a parent template that has the content that is common to the entire website and then creating child templates that inherit these common features and then adds any content unique to the child template (Figure 6).

Figure 6. A child template only adds structure and content unique to the child. All common elements are inherited from the parent template.
You will have noticed I included the sidebar navigation in the child here. It’s common for certain pages on a site to have limited navigation, so not every page will need the side navigation.
Django supports multiple inheritance too so, following on from the above example, you could have a child template that adds only the side navigation to the parent, and then have a third template that inherits from the child and adds the content.
The only limit to how you slice and dice Django’s template inheritance is practicality—if your have templates inheriting more than two or three deep, you should re-evaluate your site design.
We will be covering Django’s templates in greater detail in Chapter 8, where you will get to create your own parent and child templates for your website project.
Template Security
Django’s philosophy is that the Internet is insecure enough, without introducing security issues by allowing code execution within webpage templates. Django’s solution to template security vulnerabilities is simple—code execution is forbidden.
Django’s template tags provide display logic only, this includes:
- Displaying variables—this can be simple text like a users name, or more complex data like HTML formatted text.
- Choosing which content to display based on logical check(s), e.g., if a user is logged in, then display user menu or user-only content.
- Iterating over lists of data—most often used to insert database information into HTML lists.
- Formatting the data—for date formatting, text manipulation and other filters that act on the data.
Things you can’t do in a Django template:
- Execute Python code
- Assign a value to a variable
- Perform advanced logic
Django’s templates also add additional security features like automatically escaping all strings, Cross-Site Scripting and Cross-Site Request Forgery protection. These last two topics are beyond a beginning text, but it’s helpful to understand that Django’s templates are secure by default, so you don’t have to worry about introducing security issues into your website accidentally.
Django Views
Django’s views are the information brokers of a Django application. A view sources data from your database (or an external data source or service) and delivers it to a template. For a web application, the view delivers web page content and templates, for a RESTful API, this content could be properly formatted JSON data.
The view makes decisions on what data gets delivered to the template—either by acting on input from the user, or in response to other business logic and internal processes.
Each Django view performs a specific function, and has an associated template. Views are represented by either a Python function, or a method of a Python class. In the early days of Django, there were only function-based views, however as Django has grown over the years, Django’s developers added class-based views to Django.
Class-based views add extensibility to Django’s views, as well as built-in views that make creating common views (like displaying a list of articles) easier to implement. Don’t worry too much about the differences between function- and class-based views now, we will be covering both in more detail later in the book.
To ease the burden on programmers, many common display tasks have built-in views in Django. There are four built-in function based views for displaying error pages:
- The 404 (page not found) view
- The 500 (server error) view
- The 403 (HTTP Forbidden) view
- The 400 (bad request) view
There are also several class-based views for simplifying common display tasks. They include:
ListView
for displaying a list of data objects (e.g. list all articles)DetailView
for displaying a single object (e.g. individual article)RedirectView
redirects to another URLFormView
for displaying a form
Additional class-based generic date views for showing day, week, month and yearly collections of objects like blog posts and articles are also provided.

Like the Content? Grab the Book for as Little as $5!
Other than providing you with a convenient resource you can print out, or load up on your device, buying the book also helps support this site.
eBook bundle includes PDF, ePub and source and you only pay what you can afford.
You can get the paperback from Amazon.
URLconf—Tying it all Together
Our website is not much use if we can’t navigate around it—we need to tell the view what to display in the browser, based on what the user has requested.
Navigation in a Django website is the same as any other website—pages and other content are accessed via URL. When a user clicks on a link on a website, a request for that URL is sent to Django (Figure 7).

Figure 7. The browser request for you site homepage is sent directly to Django.
Once Django receives the requested URL, it must decide which view will deal with the request. You, as the programmer, decide which view to serve at which URL by creating a URL Configuration (URLconf for short) in a Python file named urls.py
(Figure 8). When Django finds a URL in urls.py
that matches the requested URL, it calls the view associated with that URL.

Figure 8. Django maps the requested URL to a view.
The selected view then renders the content to a template, as per the business logic in the view and sends the rendered content back to your browser for display (Figure 9).

Figure 9. The view then tells Django what template to use when sending content back to the browser.
Of course, this is a simplification—Django can collect much more complex data from the browser than a URL, and views don’t just render web pages. There is also a whole other layer of Django goodness that sits between the browser request and your view’s response (which Django rather cleverly calls middleware
) that allows you to do tons of cool stuff with your data, but these are advanced topics for another book.
The takeaway here is, regardless of how complex a website gets, this simple process underlies all of the communication between Django, the browser and the end user.
So that’s about it for our high level look at the structure of Django and how Django communicates with the browser to show your site content.
As I said before don’t be worried if you’re still a bit confused about some of this. As you dig in and start developing actual Django applications, it becomes much easier to grasp how it all works.
In the next module we’ll install Python and Django on your computer and then go ahead and create your very first Django application.