"All things being equal, which they never are" (Manager Tools), I'd choose Django over Grails for a new, green-field project. However, given the constraint to run in a Java environment, I'd gladly choose Grails over the other Java/J2EE frameworks I'm familiar with. (Django on Jython would be a contender as would Wicket, but I don't have hands-on experience with either.) This is not a slam on Grails.
Here are some of the reasons I prefer Django over Grails:
- Development Speed (not runtime performance): running (a trivial number of) unit tests for Grails on my machine took about 15 seconds (with Folding@Home in the background). Django unit tests typically only take me a couple of seconds (for a trivial number of tests). Integration tests in Grails were 30-40 seconds; Django might be 5 seconds. Although Grails will reload the running webapp when you make a change, sometimes things are really buggered, which requires a full restart. That seemed to happen more often in Grails than Django, and restarts take ~20 seconds vs. 2 seconds.
Compared to the 5-7 minutes I've seen WebSphere to restart an application, Grails is blazingly fast. But the 15-30 seconds that many operations take in Grails is long enough for the mind to wander, which is not good.
Update: a commenter pointed out the (under-documented) interactive mode of Grails. That speeds the edit-test-edit loop considerably.
- Voodoo: both Grails and Django do some voodoo behind the scenes to reduce the amount of chimp programming (e.g., non-DRY boilerplate) the programmer has to do. This voodoo involves topics of the high priests like meta object programming that mere mortals typically don't have to worry about. Maybe it's just that I don't have as much "time behind the wheel" with Grails, but I feel like its voodoo leaks out a bit and is too voodoo-rific. A Grails programmer has to be aware of which methods are dynamically added to a class in order to separate unit tests (no voodoo) from integration tests (full voodoo). And, although I like the power of dynamic finder methods like User.findByName(), it kinda bugs me that the code for that doesn't exist somewhere that I can see (you know, on punch cards!) You don't see the dynamic methods on a Django class, but there are a lot fewer of them, so it seems less voodoo-rific. Again, maybe more time behind the wheel of Grails would make me feel more comfortable.
(As an aside, when I taught Python and Django in Spring 2009, the students didn't even notice the voodoo of fields on models in Django until I pointed it out to them. Then, I exploded their heads with MOP.)
- View Technology: I have a long-standing personal preference for templates instead of ASP/JSP-like mark-up languages, and I'd lump Grails GSP pages in the latter category. Back in the day, Jason Hunter wrote an essay called The Problems with JSP that really stuck with me. GSPs are much, much better than the Model 1 JSP pages that Hunter talks about, but they still feel similar enough to make me think about using something like Velocity with Grails. Django kicks templates up a notch by having inheritance with templates, which I really love. (Even if Django didn't invent template inheritance.)
- Dynamic Language Issues: This is a real unfair comparison because I've been using Python for 15 years, but I felt that errors in Grails/Groovy were more cryptic and hard to find compared to Python. If I typo the named parameter to a method in Python, it lets me know immediately. More than once in Grails I misspelled a named parameter to a constructor, which failed silently and then lead to a validation failure later when I went to save the object. Some of that is from lack of experience with Groovy/Grails - i.e., learning what error messages really mean. But still, Python seems to fail in a more helpful way. (I'd say Python fails gracefully, but if anything it's the opposite: very loud - "you dumb-ass, there is no parameter called recipent" when I misspelled recipient.)