Django and NIH

Published October 21, 2006. Filed under: Django, Frameworks.

Just so you know, Django is a smug, arrogant framework that doesn’t play nice with others. The developers are smug, arrogant assholes who don’t care what anyone else does or what other tools are available, and who always insist on doing things their way. Django absolutely refuses to support cool “standard” Python tools and libraries unless they were implemented first for Django. Just stay the hell away from it, and teach those goddamned Django people a lesson by doing so!

Or at least, that’s the impression you’d get from reading the rants some people periodically launch against it. I understand why this particular dead horse gets dragged out and flogged every once in a while (and I understand why, on several occasions, the flogging has been done by developers of other Python web frameworks), but understanding why it happens doesn’t make it any less wrong. And of course there’s an entry in the Django FAQ about why we’ve “reinvented” a number of things, and has been pretty much since day one, but for some reason people either don’t read it or just dismiss it out of hand.

So let me try to set the record straight.

NIH Syndrome

The “NIH” stands for “Not Invented Here”, and is a common ingredient of bad software projects — rather than looking at what’s available and figuring out what they can re-use, such projects ignore existing work and proceed to re-invent everything for their own use. If it didn’t come out of the project originally, it doesn’t get used.

From the outside, especially now, it’s easy to fling that accusation at Django: we have our own object-relational mapper, our own templating system, our own middleware system… it sure looks like we’re suffering from a major case of NIH. But that’s a misleading impression, and to understand why we have to go back a ways in time.

Django began its life a number of years ago and coalesced, one piece at a time, out of the needs of the developers here at World Online. The key word here is “a number of years”; components of Django predate a lot of the things we’re often accused of “reinventing”. That shoots a big, gaping hole in the NIH argument, because it’s really hard to use a third-party tool that doesn’t exist yet.

Moving forward

Django has certainly evolved a lot since then, and high-quality tools have come into existence and matured independently of Django, and — in my own admittedly biased opinion — I think we’re doing an OK job of appropriately using them as we go. For example:

I could keep going on and on about the various third-party tools and standards Django uses and all the ways you can integrate more stuff if you want to, but hopefully the above will be enough to indicate that anyone accusing us of having NIH blinkers is full of it. Nevertheless, there are two things that keep coming up over and over again…

WSGI middleware versus Django middleware

One thing people ask a lot (well, one particular person asks it a lot, at least) is why, since Django can speak WSGI, it implements its own middleware system instead of taking advantage of the existing ecosystem of WSGI middleware. This seems like classic developer arrogance, right?

Well, not really. If you want to use WSGI middleware instead of Django’s, then go for it — we won’t yell at you if use a WSGI gzip module instead of Django’s GzipMiddleware, for example.

The problem is that you can’t always use WSGI middleware or other common WSGI tools. Django is heavily committed to also working under mod_python; if nothing else, it’s the standard deployment setup here at World Online, and the one we recommend to our clients when we sell them Django-based applications. And mod_python, according to its official FAQ, doesn’t really do WSGI yet; if you need mod_python and WSGI, you need to go fetch a third-party module and set it up yourself.

It’s kind of hard to use WSGI middleware when you don’t have a WSGI server.

And it’s a very good argument in favor of Django having its own middleware system which implements common needs like content encoding, caching, error handling, etc. It’s also why Django has two slightly different entry and exit points — one speaks mod_python and the other speaks WSGI. It’s not fun or pretty to need that, but what are you gonna do?

Templating

It’s true that now there are approximately eleventy billion Python templating toolkits out there, and some of them are pretty darned good. So why does Django still have its own different templating system? Off the top of my head, I can think of a few good reasons:

It’s also kind of amusing that some people apparently like Django’s template system so much that they’ve built standalone versions of it for use elsewhere (even in other languages — there’s a templating system available now for Rails that uses identical syntax to Django’s).

Can we put this to rest, then?

There’s a big difference between NIH and “we looked at what was available already and didn’t find anything suitable”. There are a number of places where Django has chosen to do its own thing, but those have been informed choices, made with an understanding of what existing tools were available.

So could we stop flogging the dead horse?