A slightly different take: imagine for a moment that we’re not talking about Django, but about web development in general. We could – and some frameworks encourage doing this, at least at the start – just write a single file and call it
the_website.py and put absolutely all the code for our web site in that file.
But after a while that would get unwieldy. If, say, someone needed to go edit a particular thing, or add a new feature, there’d be a lot of code for them to scroll/search through to do it, and even with good code-indexing and searching tools the cost, in developer time, of finding the right things in that file would grow and grow.
So at some point we stop using the single-file approach and instead start maintaining separate files. And probably we settle on a way of doing this that’s based on some kind of logical structure. MVC is one option, but not the only one. And things get better for a while.
But inevitably the code will keep growing. Say we went with MVC; at some point we might have dozens or hundreds or even thousands of data-model classes in the models file, and the same for the other components. The problem is back: how can developers effectively engage with and work on this?
And again the answer is usually going to be separating things based on some kind of logical structure. One possible structure (again, not the only one) is to examine the functionality, and group together the bits of code that implement each general piece of the site’s functionality. So maybe all the auth and user code in one place, all the blog code in another place, all the marketing-lead-form code in another place, and so on.
And at this point we’ve arrived at something resembling Django: our site is composed of multiple pieces of functionality, each of which is implemented in a relatively self-contained way, and each of which uses a standard organizational pattern for its own components (models, views, and so on).
Now, not everybody necessarily needs all this – there will be plenty of projects that never grow all that large – and not necessarily everybody who needs this will do it (I’ve worked on my share of codebases that used the “only a few files, all of them huge” approach). But as a general pattern, it’s useful enough that it might be worth showing it to people up-front and encouraging them to adopt it.
And especially for Django, which wants to provide at least a certain amount of functionality pre-implemented for you, this is a useful approach. Imagine if, in order to write your first Django app, you had to scroll around in files that also contained the complete implementations of the contrib apps, for example. Even for experienced developers that would probably be annoying and difficult; for newer developers it would be much worse. So rather than starting with the “everything all in one place” approach, it makes sense for Django to introduce you to the idea of separating functionality into specific apps right from the start.