Sometimes Django is described as MVC — Model-View-Controller. The problem with that is that people will either:

come with baggage from existing MVC frameworks, which might be nothing like Django,

frameworks, which might be nothing like Django, or end up at something like the wikipedia page on MVC , which describes an architecture which is very unlike Django’s.

The classic MVC architecture is about managing state. Suppose you have a GUI that allows you to, say, view and edit a drawing:

You’ve got to store the drawing in memory somewhere.

You’ve got to display the drawing on the screen.

You have controls that allow you to modify the drawing e.g. change the colour of a shape.

And you’ve got to display the changes when that happens.

The controller tells the model to change, and the model notifies the view in some way (preferably by some kind of pub/sub mechanism that allows the view to be fairly decoupled from the model).

MVC is primarily about managing the changes in state so that everything is kept in sync. Model, View and Controller are all things that exist at the same time in memory (possibly running in different threads or processes), for extended periods, with their own state, and have to interact with each other.

Django’s Model-View-Template is quite different from this.

In MVT, there is no state. There is only data. For the purposes of most HTTP requests (GET requests), the data in the database is treated as an immutable data input, not state. It could be said that the name ‘view’ is misleading, since it implies reading, not writing, i.e. GET requests not POST requests. A better name might be ‘handler’, because it handles an HTTP request, and that is the terminology used by most Django REST frameworks.

In HTTP, stateful interactions can be built up by modifying data on the server, and modifying data on the client (cookies). But these interactions are bigger than the scope of a single page view. The browser holds one half of the state — the state of the current page, and cookies — and the session database holds the other half.

But when it comes to responding to an HTTP request, Django’s MVT has a complete lack of state. Many web pages are essentially pure functions of the inputs — an HTTP request and the data in the database — so it is clear that MVT is not intrinsically about state.

Of course, there is data modification. POST requests are about that. But these do not result in views being ‘notified’. Classic web apps handle state by side-stepping it completely. If a user knows that the ‘state’ of the system has changed (i.e. new data in the database), the user presses ‘Refresh’, which:

throws away all the state (i.e. the current state of the browser), with the exception of the pieces of state that identify what the user was looking at - the URL , and the site’s cookies.

, and the site’s cookies. causes a brand new HTTP request asking for the document. The server responds completely from scratch: it doesn’t notify the view function or the template, it runs over from the beginning.

So, if anything changed, the approach is “cancel everything, start again from the beginning”.

And for the actual handling of POST requests within Django, you have a similar approach. Once the data has been updated (typically, a SQL INSERT or UPDATE), you send back an HTTP redirect to do a GET — “something changed, let’s start again from the beginning”. This is why Django’s ORM does not have an identity mapper. The model for handling state is to ignore it altogether, and just start again whenever you know that something has changed.

This is exactly the opposite of the way classic MVC apps work (including client-side, Javascript MVC frameworks) — they are all about avoiding starting again, and having live systems that can be informed about updates and keep everything in sync, by sending message between them.

There is a second aspect to MVC, which is separation of concerns. If you think of MVC as meaning “separation of code that stores data, code that displays data, and code that handles requests for data to be changed or displayed”, then Django does indeed fit that pattern.

But I don’t think the classic description of MVC is a helpful starting point at all. HTTP is different, and has its own needs which have given birth to its own architectures.