Jeff Croft

I’m a product designer in Seattle, WA. I recently worked at Simply Measured, and previously co-founded Lendle.

Some of my past clients include Facebook, Microsoft, Yahoo, and the University of Washington.

I’ve authored two books on web and interactive design and spoken at dozens of conferences around the world.

I’m currently accepting contract work and considering full-time opportunities.

Blog entry // 01.11.2007 // 6:38 PM // 33 Comments

Django and MTV

This past weekend, the RSS feed for Steve Smith’s great Ordered List blog decided to tell me a whole bunch of items were new, when they really weren’t. I’m not sure why that happened, but I’m glad it did. It resulted in my discovery of an entry he wrote back in November entitled Rails and MVC. Steve notes that several people toy with Rails a bit, but never get very far, and concludes that part of the reason for this is their lack of understanding of the Model-View-Controller programming design pattern.

Steve goes on to outline what MVC is and how it applies specifically to Ruby on Rails. It struck me that a similar piece for Django might be useful, especially since Django breaks slightly from the traditional definition of MVC. In Django, it’s MTV.

The best way to describe the MVC concept to the audience of this blog is with an analogy: MVC strives to rectify many of the same problems that the web standards movement tried to solve on the front end of things. Largely, MVC is about the separation of the different layers of a program. Just as the web standards movement was largely about breaking apart the content, presentation, and behavior layers of a web document, MVC is all about a clean break between the data, the logic that occurs around that data when a user interacts with an application, and the presentation of that data to the user. Just like web standards, right? Right.

Django is usually called an MVC framework, and justifiably so. It’s very heavily influenced by MVC and it’s even possible to argue that terminology is only place Django changes the pattern. In Django, the three core layers are the Model, the View, and the Template.

The Model

The model acts as a definition of some stored data. In a web application, this data is usually stored in a relational database, but it doesn’t have to be — it could be in an XML file, an LDAP schema, and so on. In Django, a model is a Python class that outlines the variables and methods for a particular type of data. As an example, let’s consider a blog entry (yes, it’s the example everyone does, but that’s because everyone knows what a blog entry is, so it’s easy to understand). A simple blog entry model in Django looks like this:

Our entry model has several variables (author, title, body, summary, etc.), and two methods (__str__() and get_absolute_url()). In the typical Django web application, variables are values stored in the database, and methods are Python functions that (very often, anyway) do something with that data. As as simple example, a model may have variables for first_name and last_name, and a method called full_name() that uses Python to concatenate the two together. In a typical blog application, we would have a handful of models — one that describes a blog, one that describes an entry, one that describes a tag, one that describes a user, and so forth. Each of these models can have any number of instances, or objects of that class (i.e. individual blogs, entries, tags, users, etc.).

The View

In most typical Django applications, the purpose of the view is to determine what data is to be displayed, retrieve it from the database, and pass it off to the template. In actuality, a view has the potential to do a lot more — but I’m covering the typical case here. Views are Python functions. Typically, you will have one view for each “type” of page within your site. In our blog example, we could have several views: one for the entry page that displays each post, one for a monthly archive, one for a daily archive, one for a search page — and a homepage, of course.

In most Django views, the programmer takes advantage of Django’s built-in object-relational mapping API to retrieve some set of information from the database. The ORM allows one to write Python code instead of SQL for these functions (although you can still drop down a level and write SQL directly, if you prefer). Views may also perform other kinds of tasks besides database interaction — tasks like sending e-mail messages, authenticating against some external service, and validating form input are all common. Most of the time, view functions are short (often less than 15 lines of code), and perform simple, specific tasks. In plain English, here are a couple views:

  • Get all of the blog posts created by the user “jcroft” with the tag “django” from the database, put them in a list (Python’s word for “array”) called “blog_entries”, and pass it through the template called “blog/tag.html”
  • Take the input from the form a user just filled out, validate it according to a set of rules, save it to the database, fire off an e-mail to notify someone, and then return the template “form/done.html” to the user.

The most common end point for a view function is to hand off a context to a template for rendering. A context is simply the variables that are available to the template. So, on our blog entry page template, the context will be one specific blog post. One a monthly archive page, it will be a list of all posts in that month. On the homepage, you might have a much more varied context, including the last 10 posts, a list of all the tags, a list of all the years you’ve posted in, and the 10 latest comments.

It’s important to understand that the view has no bearing over how the data is presented — only which data is presented (this is where Django varies from some other MVC frameworks). How the data is presented is the job of…

The Template

In a typical Django web application, the template is simply an HTML page with a few extra goodies. Django’s template language can actually create any sort of text file (XML, email, CSS, Javascript, CSV, etc.) — but again, I’m covering the common case here. As I said, the template receives a context from the view . Its job, then, is to organize those context variables (using any of their attributes or methods from the model) into an HTML page that will be displayed by the browser. So, if the context of a template is a single blog post with the variable name entry, we might craft a template like this:

Of course, you’d do a fully-qualified HTML page with a head, and body, and so forth — but you get the idea. Django’s template language is designed to be accessible by designers who aren’t necessarily programmers. It offers several basic tags, as well as a large selection of built-in filters for modifying the output of variables and methods (for example, formatting a date string or lowercasing text that isn’t lowercase in the database). It contains basic programming constructs, such as if statements and for loops, which are often needed for presentation logic. But, unlike some other template languages, you can not arbitrarily put Python code into a template. The language is intentionally limited so as to encourage you to properly separate your presentation logic from your business logic. Seasoned programmers sometimes find this limiting. Having used the Django template language perhaps more extensively than anyone else anywhere, I can assure you: if you can’t do it with the Django template language, it’s probably because you shouldn’t be doing it with the Django template language. It’s got everything a designer needs for presentation — your business logic belongs in the view.

The URL Configuration

There is one final piece of the Django stack: the URL configuration (usually called a URLConf by Djangoers). This is simply a mapping of URLs to the views that should handle them. You’ll recall above that we create views for each type of page within our site — and each view is a Python function. The URLConf’s job is to read the URL the user has requested, find the appropriate view to handle it, and pass any variables along that the view will need to complete its job.

URLConfs are constructed with regular expressions, giving you absolute control over the URLs for each part of your site. This is a nice abstraction that many other frameworks don’t offer. It follows along with the Python philosophy that explicit is better than implicit, having you spell out exactly what you want your URLs to be, instead of implying them from your function names, directory structure, etc.

Beautiful URLs are cool, and Django’s URLConf setup lets you achieve them. Here’s an example URLConf:

As you can see, the first URL pattern contines a simple regular expression ('^$'), which equates to the root level of the site — when found, it processes the homepage function. The second line contains a much more complex regular expression, which evaluates urls in the format /2007/jan/10/iphone-most-revolutionary-device/ and passes the various bits (year, month, date, slug) off to the blog_entry view function.

Putting it all together

Having looked at each piece of the Django puzzle, let’s consider how they work together for a typical request. Consider the homepage of JeffCroft.com. When you visit that page, the basic steps that occur are:

  1. Django searches my URLConf for a URL that matches the one you’ve asked for (in this case, ”/”).
  2. The URLConf specifies that the appropriate view is jcroft.homepages.views.homepage, so Django processes that view function.
  3. The view function for the homepage uses the Django database API to request several bits of data from the model layer. Among them: the latest blog posts, the latest flickr photos, the latest ma.gnolia links, the selections of music, books, and so forth from Enjoying, and so on.
  4. The model layer interacts with the database to find these requested items, and returns them to the view.
  5. The view passes these items as variables through the template, which is evaluated and results in an HTML page.
  6. This HTML page is passed on to the browser.

Wrapping it up

To be sure, this is a very basic overview, and my example of how a typical page request happens in Django is a simple one. Hopefully, though, it was able to give you a basic understanding of the duty of each layer in Django’s “MTV” stack.

Comments

  1. 001 // katy lavallee // 01.11.2007 // 7:27 PM

    I really like your simple overview of the framework.

    Do you know why the Django people might think it would be less accurate to call the view a controller, and the template a view? It makes more sense to me that way… but maybe I never understood what models, controllers, and views are supposed to mean in the first place.

  2. 002 // shelbybark // 01.11.2007 // 7:28 PM

    Great article, Jeff. I have to admit to jumping in to Django before completely learning to swim. So, it is always helpful to read this type of article. It helps with fluency.

  3. 003 // Jeff Croft // 01.11.2007 // 8:05 PM

    @katy: I’m afraid I can’t answer that very well. Django is really the only MVC-like programming I’ve ever done, and I don’t fully understand how it differs from “traditional” MVC. I have read others say the same as you, though — that Django’s “view” is pretty similar to what is traditionally called a “controller” and Django’s “template” is in line with what is normally thought of as a “view.”

    @steven: I jumped in before I could swim, too. Nothing wrong with that, I don’t think — it’s how we learn!

  4. 004 // Adrian Holovaty // 01.11.2007 // 8:19 PM

    Katy: See our FAQ entry that answers that very question. Also see the relevant passage in the Django Book.

  5. 005 // Paul Barry // 01.11.2007 // 8:35 PM

    Jeff,

    I agree with Katy. The article is a little confusing because in the beginning you say:

    It struck me that a similar piece for Django might be useful, especially since Django breaks slightly from the traditional definition of MVC. In Django, it’s MTV.

    Which leads me to believe the article is about how Django’s MTV is similar to, but slightly different from MVC. But as I read the article, I realized that there is no difference, and you are just explaining how Django implements MVC.

    Calling the View “Template” is no big deal, but calling the Controller “View” seems confusing. So I’m still wondering, is there reason why Django uses the MTV names instead of MVC, or is that just the way it is?

  6. 006 // Jeff Croft // 01.11.2007 // 8:50 PM

    Which leads me to believe the article is about how Django’s MTV is similar to, but slightly different from MVC. But as I read the article, I realized that there is no difference, and you are just explaining how Django implements MVC.

    Sorry for the confusion.

    So I’m still wondering, is there reason why Django uses the MTV names instead of MVC, or is that just the way it is?

    Only the developers of Django can really answer this. You’re in luck, because one its creators just put two links that try to explain it in this very thread. Did you read them?

    I did, and it seems the key take-away point is that in traditional MVC, the view defines not only what data is presented, but how it is presented. In Django, the view defines only what data is presented (the template defines how that data is presented).

  7. 007 // Paul Barry // 01.11.2007 // 9:01 PM

    Ok, I just read the FAQ Entry that Adrian posted.

    Well, the standard names are debatable.

    Obviously

    In our interpretation of MVC, the “view” describes the data that gets presented to the user. It’s not necessarily how the data looks, but which data is presented. The view describes which data you see, not how you see it. It’s a subtle distinction.

    Ok, so the “controller” controls what data gets presented.

    So, in our case, a “view” is the Python callback function for a particular URL, because that callback function describes which data is presented.

    And in the case of other frameworks, a “controller” is the function for a particular URL, and that function controls which data is presented.

    Furthermore, it’s sensible to separate content from presentation — which is where templates come in. In Django, a “view” describes which data is presented, but a view normally delegates to a template, which describes how the data is presented.

    In other frameworks, a “controller” controls which data is presented, and a controller normally delagates to a view, which decides how the data is viewed.

    Where does the “controller” fit in, then? In Django’s case, it’s probably the framework itself: the machinery that sends a request to the appropriate view, according to the Django URL configuration.

    Yes, that stuff is part of the controller.

    If you’re hungry for acronyms, you might say that Django is a “MTV” framework — that is, “model”, “template”, and “view.” That breakdown makes much more sense.

    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.

    In other words, you are saying “you’re right, it is MVC, we just use different names”. That’s fine, I can accept that. The point remains that I don’t see a reason here that say why you decided “view” was a more appropriate name than “controller”. If really don’t like the name “controller”, I could see “action” or “handler”, but “view”?

  8. 008 // James // 01.11.2007 // 9:05 PM

    Thanks for this, Jeff.

  9. 009 // Jeff Croft // 01.11.2007 // 9:10 PM

    In other words, you are saying “you’re right, it is MVC, we just use different names”. That’s fine, I can accept that. The point remains that I don’t see a reason here that say why you decided “view” was a more appropriate name than “controller”.

    As I said, Paul, you would really have to ask the Django developers. I do not know. You keep asking addressing this question at me, as if I picked these names. I didn’t, and I don’t know why they were picked.

    Sorry.

  10. 010 // Paul Barry // 01.11.2007 // 9:16 PM

    I did, and it seems the key take-away point is that in traditional MVC, the view defines not only what data is presented, but how it is presented. In Django, the view defines only what data is presented (the template defines how that data is presented).

    I’m not sure what you are referring to by “traditional”, but I can say that the view in all the Java web frameworks that I am familar with ([Struts][1], [Spring MVC][2], [Webwork][3], [Stripes][4]), the view is definitely not responsible for deciding what data gets presented.

    It works the same as in Django, the controller loads the data into some kind of context (in Java, typically request attributes), and then the request is forward to a view (typically a JSP page, Velocity or Freemarker template), which builds the HTML using the data in the context.

    Ruby on Rails also works this way, except by making the data that is stored in controller’s instance variables available to the views.

    But the definition of the view from [Wikipedia][5] says:

    MVC is often seen in web applications, where the view is the HTML page and the code which gathers dynamic data for the page.

    So if you are going by that definition, then yes, Django differs from “traditional” MVC, but in the same way the Java MVC frameworks and Rails do.

    So in other words, Django’s MTV pattern does differ from the Wikipedia definition of MVC (which one would assume represents the “traditional” definition), but only differs from Java and Rails in the naming, not the way it works. And I personally find the naming confusion. :)

    [1]: http://struts.apache.org/ [2]: http://www.springframework.org/d… [3]: http://www.opensymphony.com/webw… [4]: http://stripes.mc4j.org/confluen… [5]:

    Model–view–controller (MVC) is a software architectural pattern for implementing user interfaces. It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user.[1][2]

  11. 011 // Jeff Croft // 01.11.2007 // 9:20 PM

    In other words, Django’s MTV pattern does differ from the Wikipedia definition of MVC (which one would assume represents the “traditional” definition), but only differs from Java and Rails in the naming, not the way it works.

    Which would explain this line from my original post:

    It’s very heavily influenced by MVC and it’s even possible to argue that terminology is only place Django changes the pattern.

  12. 012 // Scott McCracken // 01.11.2007 // 9:47 PM

    Guess it’s impossible to please everyone, Jeff. Thanks for taking the time to write this out—for those of us treading water after a belly-flop in the deep end of the Django pool, it’s much appreciated.

    Your code display in this entry is fantastic. I’d imagine it takes a long time to wrap specific bits in span tags for color coordinating, but the end result is well worth the effort—very Text Mate-ish.

  13. 013 // Jeff Croft // 01.11.2007 // 9:58 PM

    Your code display in this entry is fantastic. I’d imagine it takes a long time to wrap specific bits in span tags for color coordinating…

    Not really. :)

  14. 014 // Dru // 01.11.2007 // 10:13 PM

    I like that python supports stand alone functions. And I also like the MTV approach. One of the big differences I think is that according to wikipedia Controllers:

    Processes and responds to events, typically user actions, and may invoke changes on the model.

    In the web we really don’t have events we just have requests, so the team has taken the traditional Controller and hidden it from us, allowing us to further focus on the problems we want to solve.

  15. 015 // Steve Williams // 01.12.2007 // 5:45 AM

    Very nice code implementation Jeff, as others have said.

    Unfortunately, the code sections didn’t make it through to my Safari RSS view, which left me a little confused until I visited the site proper…

  16. 016 // guioum // 01.12.2007 // 6:14 AM

    Great article!

    Maybe some parts can be included in the django book. Thanks.

  17. 017 // Josh Blount // 01.12.2007 // 6:37 AM

    Nice Jeff, thanks a lot for this simple explanation.

    Someday you should get the official “evangelist” title for the Django project!

  18. 018 // Brade // 01.12.2007 // 8:12 PM

    Jeff, thanks for this great summary. I have dinked with Rails and have been using CakePHP where I work. I agree with Paul that Django did not necessarily need to use different terms than MVC to describe how it’s working, but that’s not as important as how good it is as a framework. We are excited about looking at Django for one of our big projects. I have used python before (to write a simple email client) and liked it, so I’m looking forward to digging in.

  19. 019 // Mike // 01.13.2007 // 7:14 AM

    Would be great, if you would have also posted the view.

    It’s always nice to compare how people write views.

  20. 020 // Jeff Croft // 01.13.2007 // 11:30 AM

    Mike-

    For most simple cases, I would almost certainly use Django’s built-in generic views. They’re well-made, easy to use, flexible, and save me the time and effort of writing a view. :)

  21. 021 // Andrei Maxim // 01.14.2007 // 1:11 AM

    Just a quick note: Steve Smith’s site migrated recently from Wordpress to Mephisto. Right now it’s one of the featured Mephisto blogs.

  22. 022 // mark // 01.14.2007 // 8:03 PM

    from jcroft.blogs.views import blog_entry

    What file/path does this point to in the directory structure???

    What is blogs? A folder? A file? Still trying to understand…

  23. 023 // Jeff Croft // 01.14.2007 // 8:17 PM

    @mark: That’s a regular Python import statement using Python’s namespaces (i.e. there’s nothing Django about it — it’s just Python). Python modules are directories or files in your Python path. In this case, jcroft is a directory, blogs is a directory inside of it, views is a file inside of it (the filename is actually views.py), and blog_entry is a function in the views.py file. You’ll recall I said each view is simply a function — this is just the path to that function.

    This sort of namespacing is common amongst modern programming languages — here’s a Wikipedia article.[1][2] Namespaces provide a level of indirection to specific identifiers, thus making it possible to distinguish between identifiers with the same exact name. For example, a surname could be thought of as a namespace that makes it possible to distinguish people who have the same given name. In computer programming, namespaces are typically employed for the purpose of grouping symbols and identifiers around a particular functionality.

    ) on it, if you’re curious.

    As for why this is the namespace I’ve chosen:

    Django differentiates between “projects” and “applications”. A project, usually, is a single website. A project may contain several applications. Here, I’ve got a project called jcroft (which makes up jeffcroft.com) and an application in that project called blogs.

  24. 024 // mark // 01.14.2007 // 8:44 PM

    Cool! Thanks! Makes sense!

  25. 025 // Reinmar Müller // 01.15.2007 // 4:32 AM

    Paul,

    The point remains that I don’t see a reason here that say why you decided “view” was a more appropriate name than “controller”. If really don’t like the name “controller”, I could see “action” or “handler”, but “view”?

    This is certainly not the “official” take on the issue, and it might be a shaky definition, but the following reasoning makes sense to me personally:

    The view is a way of looking at and working with data — what data do I want, how do I want it to be structured? You can use the same set of data in various ways (in different views):

    • just pass it through
    • process it in some way before
    • filter it down further according to certain rules
    • etc.

    Note that I’m not talking about the presentational layer here (that only comes in the template). What I’m trying to say is you could see the view as the “point of view” from which you’re dealing with data or doing any type of work at that specific point in your app. Hope that helps.

  26. 026 // Fredrik // 01.16.2007 // 1:40 AM

    the view is definitely not responsible for deciding what data gets presented”

    ROTFL. I suppose I’m the only one here who’s old enough to have done MVC work before the web, but it’s rather amazing to see how latecomers like Java can take something simple and clever, mess everything up, and then make people believe that the botched implementation is somehow the “right way to do it”.

    (in traditional MVC, the View is responsible for pulling data from the Model and displaying it, and the Controller is responsible for interacting with others (primarily the user) and updating either the View or the Model as necessary. In a traditional web context, the View and Controller responsibilities are always split between the web server and the client, where View components on the server produce HTML for View components in the browser, and Controller components in the browser produce HTTP requests for Controller components in the server. In a full-blown “web 2.0” system, most of the View and Controller work is done in JavaScript, in the browser, and the server is increasingly acting as a pure Model interface.)

  27. 027 // Dave // 01.17.2007 // 8 AM

    Darn it all - I had really meant to become the defacto Django evangelist. But I had a few things going against me:

    1. No public Django-powered site yet
    2. Jeff works at World Online :)

    BTW - Jeff, you’ve always held that you’re not a “programmer” but I hate to break it to you - you’ve certainly proven with this site that you indeed are a little bit of a Python programmer. Welcome to the club.

  28. 028 // pauldwaite // 03.27.2007 // 7:29 AM

    Great article: lovely explanation of how Python works for non-programmers such as myself.

  29. 029 // Guescancerce // 12.06.2007 // 10:59 AM

    hm.. just wanna say thank you

  30. 030 // Brian // 01.18.2008 // 10:05 AM

    nice article. may get me a job.

    the semantic thing about “view” makes the learning curve a bit steeper (esp. as I look at other MVC-oriented sites) but is not a big deal. jargon is part of almost every learning experience - if my interpretation of an analogy is different from the authors, i’m up the creek, but once i start understanding, it’s usually easy.

    my nit: the word data is a plural word.

    the data are …

    the data look like …

  31. 031 // huxley // 04.29.2008 // 7:58 PM

    @ Brian,

    my nit: data is both a plural and a singular noun in English. If we were speaking Latin, you might have had a point.

    Just to blow your mind, check out a decent dictionary to see what the plural of “datum” is in civil engineering or surveying.

  32. 032 // alan // 12.07.2008 // 10:56 PM

    Thanks for the writeup. Very helpful.

    Also, Just wanted to comment that reading the text over the brown background hurts my eyes. Reading white text on a dark background seems to be the problem. maybe others have had this problem as well.

  33. 033 // Bhargava // 12.18.2008 // 10:49 AM

    Thanks for this wonderful post. Very helpful.

Tags for this entry
Links in this entry