I go a little way in this direction. I rarely go as far as dependency injection for business logic, but a good habit I picked up is to ensure that my business logic is put in appropriate places somewhere other than view functions, and all queries are kept with the models (ie. as Manager methods), and all the presentation operations are template tags and filters. That way the view contains little more than just connecting queries to business logic to templates, which is useful when it comes to understanding how an application was plumbed. In fact I've just used this to quite rapidly port a Postgres backed Django app to entirely ElasticSearch backed. Because I had defined my queries in terms of Manager methods it wasn't hard to reimplement them one-by-one with equivalent ElasticSearch searches. It would have been much harder if I'd littered .filter()/.exclude() calls all over the place.<br>
<br>Something that was useful for that and slightly mitigates Django in this regard is that the 
lazily-evaluated, sliceable QuerySet has become something of a pattern, 
to the extent that you can sometimes sort of plug QuerySet-like result objects, such as 
those from PyES, MongoEngine, couchdb-python etc, into logic 
built around querysets. It also helps that Django templates are very forgiving.<br><br>While interviewing for Python developers I found numerous candidates who when presented with a generic OOP problem would immediately start writing Django models, with the result that the solution exhibits exactly the kind of dependency problems that article describes. For similar reasons, we now have an application where the cryptically terse dictionary keys favoured by hardcore MongoDB geeks leak everywhere, including template code and client-side javascript.<br>