I’ve been seeing some random chatter lately about the trouble with reusable apps in Django, succinctly epitomized by this remark from Luís Pedro Coelho: “the app system is not the right system to break up functionality”.
I don’t get that.
Surely, there are a lot of Django apps on GitHub that are plain crap.
Handling static media in pluggable apps is still somewhat tricky, although there’s django-staticfiles now. Some more conventions for pluggable apps wouldn’t hurt, which is something that’s definitely on people’s minds.
And some developers just don’t grasp how they should construct a piece of code in a way that makes it reusable. For example, some Django apps are little more than utility libraries, and they would fare much better as generic python modules or as WSGI middleware, perhaps with some optional Django helpers. (Surlex by Cody Soyland is a great example of a python module that is decoupled from Django while still being very easy to integrate.)
But that’s not what Coelho meant when he said that “the app system is not the right system to break up functionality”. He means that reusable apps are architecturally wrong. Not that the paradigm doesn’t always work as smoothly as it should, but that it can’t work smoothly because it’s a bad way to split up functionality. He calls it “django’s basic architectural flaw”. I disagree.
I disagree, and I think it’s a messy discussion. I see four basic talking points that we should really disentangle.
First talking point: stumbling blocks
The practical stumbling blocks that app creators face don’t say anything about the merits of the project/app abstraction, and fixing them is not a matter of overhauling the basic architecture of the system.
And we have a few ways that aid in making great reusable apps today:
- abstract and proxy models
- urlconf includes and url reversals
- creating your own views that extend existing ones (a view is just a function after all)
- exposing functionality as decorators or as middleware that people can use as they please
- the Django registration pattern and other patterns like class factories
We need more of them, but app makers have a pretty big toolkit already.
Second talking point: plug ’n play
Should reusable Django apps try to be what modules are to Drupal, extensions are to Joomla or plugins are to Wordpress, i.e. something you download, install and configure without ever writing a single line of code?
Some would go as far as suggesting that Django’s reusable apps are its biggest failure , because the system is nowhere near as smooth as in Wordpress.
I think it’s an absurd thing to ask of Django to be more like Wordpress. The reason we’re all using Django is because it is not like Wordpress, I would think.
A fellow named zap replies to Coelho that “Perhaps you shouldn’t try to use Django as an app/cms engine, but rather as a mvc framework.” Areth Foster-Webster says things with a bit more punch: “This article should be re-titled to ‘It took me 6 months to realize Django is not a swill infused CMS like Drupal.’”
The fact that Django encroaches a little on CMS territory is one of the things that make it great, but it’s easy to get overly excited about the time gains that prefab apps can bring. Be prudent.
Don’t use Django like you’d use Drupal, by mixing-and-matching reusable apps. The best Django apps are those that try to stay a bit low-level. Apps like sorl-thumbnail, staticgenerator, typogrify and south.
Third talking point: how generic is generic enough
Are we happy with apps that can be plugged into any existing Django installation, or do we expect something more? Do apps need to be really reusable ? A truly reusable app has plenty of configurability, the ability to replace the provided templates, add in new functionality that complements provided features, and so on.
Creating reusable apps in this fashion isn’t impossible, but it’s a lot of work that doesn’t always make sense. It also has very little bearing on Django. It’s part of a broader discussion: if you’re creating an application, how generic should you make it? Is there a point where an app becomes so generic as to become unusable or unmaintainable?
Armin Ronacher says:
But, again, we should separate “apps don’t work” from this particular discussion.
Fourth talking point: software architecture
Yet another important topic is how we should organize our applications internally. Model-template-view provides the basic way you organize a project in Django. But one might wonder how different pieces of functionality (apps) within a larger project should relate to each other. In Django, because each part of each application is exposed to the entire system, it’s easy to start programming to the implementation rather than to the interface.
It’s sometimes necessary to step back and evaluate whether it makes sense to (e.g.) import and use a model from another application directly, or whether it would be better to use an interface that abstracts away the specifics of that model and loosens up the coupling between your applications a bit. For smaller projects, the overhead of interfaces is probably not worth it, for larger ones it’s necessary to keep things sane.
Or sometimes Django applications might indeed not be the suitable way to split up a larger project. For big webapps, it can pay off to split up the project into multiple separate subprojects — not necessarily all using Django — that communicate using an API over HTTP.
But at this point, we’re talking about how to build big websites in a way that doesn’t lead to maintenance nightmares. Very important, difficult to get right, but it’s not about Django and it’s not even about Python.
Let’s keep these four discussions separated, and maybe then we can start making progress on each of these fronts. Without the FUD.