Django, unchained

Django is the nagging parent who forces you to eat your greens when all you want is a scoop of ice cream and a new episode of Rugrats — you might hate them as a kid, but you’ll grow impressed with them when you’re living alone and making veggie stir-fry and actually enjoying it.

The first time I used Django it felt less like a framework and more like a choose-your-own-adventure novel: it was my first exposure to the MVC methodology, and I felt like a nervous tourist being shuttled around to views.py to do some coding, and then models.py to deal with data, and an arcane settings.py file of which I still don’t understand the majority.

Starting a project was an exercise in self-punishment. Why must I spend time dealing with abstract apps and modules? Why can’t I remember the goddamn syntax for passing a variable to a method? Why can’t I just throw this into Flask, attach some methods to a URL and go to the races?

Flash forward…

I’ve had the opportunity over the past few months to work with a legacy Django app, and suddenly my appreciation for Django’s Kafkaesque rules bloomed.

The MVC apartheid makes interaction with legacy code incredibly simple. The project has been worked on by non-programmers, and it shows: raw SQL is copy-pasted in various views, conventions and comments are sparse, and entire functions are commented out. But when I get instructions to fix a routing error or (like I did this morning) fix some standardization issues regarding Persian press clippings in early 2006, the route from error to routing to backend ( to data) is surgical and natural. Everything is more or less in its place, because it has to be.

So I’ve grown to like Django a lot, and as I explore its vibrant community I’m getting a much better grasp of the design choices made. Still, I have a few issues:

Pain points

1 — Django doesn’t deal with abstract models so much as they embrace them full-fledged with an incredibly useful ORM and querying setup. However, this is hamstrung by the intentional choice to adopt a “Golden Gun” approach to DDL. When you want to create your database, you call manage.py syncdb, which scans your code and creates the appropriate tables which is super rad, except if you ever have to change anything. Decide that you want a datetime to be nullable? Nuke the database and start over. Decide that you want to refactor country ISO-codes into their own table? Nuke the database and start over. Decide that you want to change the name of a column? Nuke the database and start over.

(It should be mentioned that South helps a lot with this — but it’s not perfect, and it’s not builtin.)

2 — Django treats forms and POST requests very seriously. That is a good thing — if you’re creating a serious web app, knowing about things like CSRF tokens and proper form validation is incredibly important. What it’s not ideal for is building an MVP — my “code as much as I can insanely quickly” mindset is very much distinct from my “deal with technical issues” mindset, and being forced to think about request forgeries when I’m trying to make a simple Contact Us form is pretty rude.

(Easy solution to this — disable all of the middleware protections if you invoke runserver with debug=True.)

3 — Django needs to take better advantage of its modular app structure and emphasize that aspect of its framework from the very beginning (as in, the landing page and the tutorials.) It’s still hard for me to get my head around because I didn’t start tinkering with it until I was already well-acquainted with the framework, and I still am incredibly cautious about bringing in external apps — it feels a bit like cognitive dissonance, like I’m cheating the system. Still, I’d estimate that a majority of programmers spend precious time reinventing the wheel: things like no-fuss no-hassle login, visualization, and CRM apps would be an incredible blessing.

In conclusion —

Django is awesome. It could be awesomer, especially in the early stages of rapid development. In the meantime, it’s much easier to use Flask and let the MVC separation develop naturally.

(And sorry about the title. I couldn’t resist.)

If you liked this post, you should follow me on Twitter. (I won’t spam you, I promise!)