Model-View-Controller (MVC) in Python Web Apps: Explained With Lego

Model-View-Controller (MVC) in Python Web Apps: Explained With Lego

by Alex Coleman Mar 18, 2024 intermediate web-dev

If you’re curious about web development, then you’ve likely encountered the abbreviation MVC, which stands for Model-View-Controller. You may know that it’s a common design pattern that’s fundamental to many Python web frameworks and even desktop applications.

But what exactly does it mean? If you’ve had a hard time wrapping your head around the concept, then keep on reading.

In this tutorial, you’ll:

  • Approach understanding the MVC pattern through a Lego-based analogy
  • Learn what models, views, and controllers are conceptually
  • Tie your conceptual understanding back to concrete web development examples
  • Investigate Flask code snippets to drive the point home

Maybe you built things with Lego as a kid, or maybe you’re still a Lego-aficionado today. But even if you’ve never pieced two Lego blocks together, keep on reading because the analogy might still be a good building block for your understanding.

Explaining the Model-View-Controller Pattern With Lego

Imagine that you’re ten years old and sitting on your family room floor. In front of you is a big bucket of Lego, or similar modular building blocks. There are blocks of all different shapes and sizes:

  • 🟦🟦🟦 Some are blue, tall, and long.
  • 🟥 Some are red and cube-shaped.
  • 🟨🟨 Some are yellow, big, and wide.

With all of these different Lego pieces, there’s no telling what you could build!

Just as your mind is filling with the endless possibilities, you hear something coming from the direction of the couch. It’s your older brother, voicing a specific request. He’s saying, “Hey! Build me a spaceship!”

“Alright,” you think, “that could actually be pretty cool.” A spaceship it is!

So you get to work. You start pulling out the Lego blocks that you think you’re going to need. Some big, some small. Different colors for the outside of the spaceship, different colors for the engines.

Now that you have all of your building blocks in place, it’s time to assemble the spaceship. And after a few hours of hard work, you now have in front of you—a spaceship:

                            🟨🟨       🟨🟨

You run to find your brother and show him the finished product. “Wow, nice work!”, he says. Then he quietly adds:

Huh, I just asked for that a few hours ago, I didn’t have to do a thing, and here it is. I wish everything was that easy.

Your Brother

What if I told you that building a web application using the MVC pattern is exactly like building something with Lego blocks?

User Sends a Request

In the case of the Lego spaceship, it was your brother who made a request and asked you to build something. In the case of a web app, it’s a user entering a URL and requesting to view a certain page.

Controller Interprets the Request

When you built the Lego spaceship for your brother, you were the controller. In a web app, the controller is the code that you write.

The controller is responsible for understanding the request and taking actions based on it. It’s the controller that gathers all of the necessary building blocks and organizes them appropriately.

Models Make the Products

The different types of Lego blocks are the models. You have different sizes and shapes, and you grab the ones that you need to build the spaceship. In a web app, models help the controller retrieve all of the information needed from the database to make the products.

Once the controller uses the models to retrieve the necessary items, everything needed is in place to assemble the final product.

View Represents the Final Product

In the Lego example, the spaceship is the view. It’s the final product that your brother—the person who made the request—gets to see.

In a web application, the view is the page that the user sees in their browser.

Summarizing Your Lego Adventure

You’ve built a spaceship, impressed your brother, and connected the process to building web applications using the MVC pattern. Here’s a quick recap that you can keep handy to help you remember how this story relates back to web development.

When Building With Lego:

  1. Your brother makes the request that you build a spaceship.
  2. You receive the request.
  3. You retrieve and organize all of the Lego blocks that you need to construct the spaceship.
  4. You use the blocks to build the spaceship and present the finished spaceship to your brother.

These are generic steps. You can repeat them to construct Lego builds of many different shapes and colors.

A person building a spaceship with lego, as an analogy for building web apps with Python using the MVC pattern

With this gently watercolored image etched into your brain, you can now revisit the web app version of the process to compare them.

When Building a Web App:

  1. A user requests to view a page by entering a URL.
  2. The controller receives that request.
  3. The controller uses the models to retrieve all of the necessary data, organizes it, and sends it off to the view.
  4. The view uses the data it receives to render the final webpage and presents it to the the user in their browser.

Again, these are generic steps that your web app does many times over to serve all sorts of information and pages to your users:

MVC diagram with routes

If you mentally store this second image next to the first one, then you’ll have a complete analogy that you can refer back to whenever you want to remember what the MVC pattern is all about.

Here’s another overview, summarized in a table:

Lego Website
Wish Brother’s request URL request
Execution You Controller
Building blocks Lego Models
Presentable product Spaceship View

Nice work! Now that you’ve painted this analogy into your memory, you’ve built a solid foundation for understanding the Model-View-Controller pattern. Next, you can go a little deeper and consider what it all means from a more technical perspective, focusing on Python web development.

Exploring the Model-View-Controller Pattern in Python Web Development

When you type a URL in your browser to access a web application, you’re making a request to view a certain page within the application. But how does the application know which page to render and display?

When building a web app, you define what are known as routes. Essentially, routes are URL patterns associated with different pages. So when someone enters a URL, the application tries to match that URL to one of the predefined routes behind the scenes.

So, there are really four major components at play here: controllers, models, views, and routes.

Routing Requests

Each route is associated with a controller. More specifically, it’s associated with a certain function within a controller, known as a controller action. So when you enter a URL, the application attempts to find a matching route. If it’s successful, then it calls that route’s associated controller action.

You can start learning how the Model-View-Controller pattern works in Python web development by considering a basic Flask route as an example:

# ...

def home():

Here, you establish that the base route ("/") is associated with the home() view function, which conceptually is a controller action. When someone requests that base route, then your web app will call home().

Coding Models and Controllers

Within the controller action, you typically do two main things:

  1. You retrieve all of the necessary data from a database using the models.
  2. You pass that data to a view, which renders the requested page.

You generally add the data that you retrieve via the models to a data structure, like a list or dictionary. Then, you send that data structure to the view.

Go ahead and expand your Flask example app with these functionalities:

 1# ...
 4def home():
 5    """Searches the database for entries, then displays them."""
 6    db = get_db()
 7    cur = db.execute("SELECT * FROM entries ORDER BY id DESC;")
 8    entries = cur.fetchall()
 9    return render_template("index.html", entries=entries)

In your updated view function, you fetch data from the database in lines 6 to 8. The get_db() function that you see in this code snippet is a placeholder for a database connector function. You’ll need to write the code for this function so that it works with the database that you use—for example, a Python SQL library.

In line 8, you end up with a list, which you assign to the variable entries. Then in line 9, you send that list to the index.html template and make the data accessible through a variable that you also call entries.

Building the Views

Finally, the index.html file represents your view. Because you used the controller action to send the data structure to the template file, you can now access the data in there. You can then work with the information contained within the data structure to render the HTML content of the page that the user ultimately sees in their browser.

In your Flask app example, you can loop through entries and display each one using the Jinja syntax:

HTML templates/index.html
 4    {% for entry in entries %}
 5        <li>
 6        <strong>{{ entry[1] }}:</strong>
 7        {{ entry[2] }}
 8        </li>
 9    {% else %}
10        <li>No entries yet. Add some!</li>
11    {% endfor %}

If you have entries in your database, then your user will get to see all the entries listed one after another. You also added an optional else clause in line 9, which renders a descriptive text message if there aren’t any entries yet.

Summarizing the Model-View-Controller Pattern

Now you’ve done a second lap around the concepts of the Model-View-Controller pattern, this time using Python’s Flask web framework as a guide rail. Here’s a more detailed, technical summary of the MVC request process:

  1. A user requests to view a page by entering a URL.
  2. The application matches the URL to a predefined route.
  3. The application calls the controller action associated with the route.
  4. The controller action uses the models to retrieve all of the necessary data from a database, places the data in a data structure, and loads a view, passing along the data structure.
  5. The view accesses the data structure and uses it to render the requested page, which the application then presents to the user in their browser.

It’s not quite the same as building a Lego spaceship for your brother, but maybe you can see the conceptual similarities in the two processes.

If you want to play with the example Flask app and explore the additional code that’s necessary to run it, then you can download the code here:


It’s time to come back from time-traveling to your Lego-wielding past. You took a trip to gather memories and analogies, and applied them to improve your understanding of the Model-View-Controller (MVC) pattern for creating Python web apps.

In this tutorial, you learned how to:

  • Build a spaceship for your brother
  • Conceptualize models, views, and controllers in web applications
  • Relate the MVC concepts to concrete code examples in Flask

Do you have another analogy that you like to use to remember what the MVC pattern is all about? Share your thoughts in the comments below!

🐍 Python Tricks 💌

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About Alex Coleman

Alex Coleman Alex Coleman

Alex is an avid Pythonista and Real Python contributor.

» More about Alex

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Master Real-World Python Skills With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

Master Real-World Python Skills
With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Level Up Your Python Skills »

What Do You Think?

Rate this article:

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. Get tips for asking good questions and get answers to common questions in our support portal.

Looking for a real-time conversation? Visit the Real Python Community Chat or join the next “Office Hours” Live Q&A Session. Happy Pythoning!

Keep Learning

Related Tutorial Categories: intermediate web-dev