Something I've been up to

Jul 22, 2011 • Karen

Well, there's many things that fit that descriptor lately. I've been busy! (And not blogging about hardly any of it; oops.)

Anyway, one of those things is a new FOSS-ish project I started called "ponyjoist"! It's a Python script (soon-to-be a real Django app, so it can be run like other management commands) to make Django more Rails-like.

First, a wee bit of background: I've been sort-of learning Ruby on Rails trial-by-fire style at my internship this summer. I had thought I would be working on a Django-based project, but I got moved to a different project early on. Not only is my main project at work Rails-based--my side projects are Rails too! Which is hardly the end of the world--I see the appeal of Rails, and it's always good to learn new tools. But it's frustrating to feel coding-illiterate all over again--to know what I want to happen but not how to tell the computer to do what I want. Especially given deadline pressure. And there are a number of little things about Rails I keep running into that rub me the wrong way, things I feel Django does more sensically.

Python and Django are my first loves, my native digital tongue. Of the languages I've encountered, Python makes the most sense to me (mostly). I didn't like feeling like I'd abandoned it.

But there are two main things that I like about Ruby on Rails that Python/Django don't have.

1.) list.first / list.last notation. Sure, you can write list[0] or list[-1] in Python and get the same effect. I don't care. I find .first and .last elegant, and wouldn't mind adding them onto Python.

2.) The rails scaffold function, which takes a model and auto-creates basic controller and view files that handle that model's CRUD (create, read, update, delete) functions. Boom! Open your dev server in your web browser and, thanks to a single Rails command, you've got freaking model read-write functionality (which you can then edit to make pretty and whatever)! It's flippin' magic! It gets rid of so much repetitive busywork! Why doesn't Django have this??

It's this second gap that ponyjoist is meant to solve. The script, once I finish it, will take a Django app and a model as arguments, then edit and/or create,, and template files with basic skeleton CRUD-implementing code for that model. (Hence the name; 'django-scaffold' is already taken by an unrelated app, so instead we have the image of a Django pony made up of unfinished wooden studs! There will be an awesome logo eventually, I *promise*.)

So (once I get everything working) your initial app development workflow would then look like this:

1.) startapp appname
2.) Add the app to
3.) Install South (see South's instructions)
4.) Create that app's first model(s). Let's say one's a Person model.
5.) Run syncdb / do migrations / whatever. See: South's tutorial.
6.) Run ./ scaffold appname Person
7.) Run ./ runserver, go to localhost:8000/appname/person/, and admire your lovely new urls, views, and templates! Look at all that tedious, repetitive work you didn't have to do!
8.) Continue editing to your life's content.

I guess this touches on what I feel is one of Django's biggest weaknesses: even for building the most basic of web applications, it's painfully incomplete. The official Django tutorial isn't so much a learning tool as an advertisement--there's so many basic things that it ignores or glosses over. Like migrations. You wouldn't believe how frustrated I was, when trying to build my first Django app on my own, to find out that after the first database sync, there was no way I could edit my models successfully with just a vanilla Django install. Django doesn't have a built-in database migration function (something that Rails does have, incidentally); you have to 1.) know in advance that that's the case and 2.) have installed a separate migrations app, such as South. There's no way to take seriously a web framework that won't let you change your models after the first go; sure, you can get away with it for a silly tutorial, but it's utterly unrealistic.

The official Django tutorial also leaves out how to implement any sort of user-facing CRUD functionality, instead spending an entire page on the /admin/ interface--which, while not useless, is unlikely to be used much by any Django app that's not a newspaper or blog. Django 1.3 has such nice handling of static files and auto-generated forms now, yet those aren't in the tutorial either! If you didn't already know those features existed, you'd be hard pressed to find them. (My Django book dates to version 1.0, so it doesn't mention them either. :P)

Finally, on a little more advanced note, there's the issue of dependency handling. Django does zero of this; you have to use a completely separate app like Buildout to manage dependencies. Whereas Ruby on Rails has rubygems and/or RVM, plus bundler, basically by default. Handling Rails dependencies, in the vast majority of cases, is hilariously simple. (And disgustingly slow, yes, but that's a different problem.) This encourages reuse of gems among Rails developers (and fulfills Django's espoused Don't Repeat Yourself (DRY) philosophy in a much more cosmic sense). The amount of analogous reuse of Python eggs and Django apps is tiny in comparison, as far as I can tell, and I wouldn't be surprised if the lack of automagic dependency handling contributed to that.

I'm not saying that Rails is better than Django--as I've mentioned earlier, I prefer the latter by *far*. But I do think that Django could stand to take some lessons from Rails in order to make it more accessible to designers and beginning developers and just plain faster and easier for anyone to program with. We don't have to have South or Buildout or ponyjoist (or something else CRUD-focused) built into Django; people like having a choice of tools and that's perfectly fine. But I want a damn tutorial that takes a good hard look at what real, actual Django web app development involves and actually goes through all the components needed for self-sufficiency (not in complete detail, *obviously*, but you can't very well look up docs on something you don't know you need and don't know exists). And if we can build some little hacks to make a tutorial like that more simple...well, that's what I've been working on the last week. :)