django & appengine
What I was really interested in was using Django together with appengine. I’ve used appengine before with the builtin webapp framework. Whilst it’s good, it’s simplistic and I found myself building layers on top quickly.
Looking through the docs, the first thing I see is Running Django on Google App Engine. But this says that the builtin django is obsolete and I should be using django-nonrel. There is further documentation on this, Running Pure Django Projects on Google App Engine. This approach is interesting. It’s encouraging you to not be appengine specific, the way that you are with webapp’s default setup.
django-nonrel is made up of several components; you should start by looking at djangoappengine. You’ll need to download all five components.
- django-testapp (strictly, this is optional, but it’s a good idea for referring to)
You’ll also need the appengine SDK in case you don’t have it.
Once you’ve downloaded everything, import the necessary bits into a project you made with the appengine SDK.
% pwd /Users/dom/work % cp -r $APPENGINE_SDK/new_project_template hellodjango % cd hellodjango % mv ~/Downloads/wkornewald-django-nonrel-c73e6ca3843d/django . % mv ~/Downloads/wkornewald-djangotoolbox-f79fecb60e6d/djangotoolbox . % mv ~/Downloads/wkornewald-django-dbindexer-48589f5faad4/dbindexer . % mv ~/Downloads/wkornewald-djangoappengine-f9175cf4c8bd djangoappengine % ls -l total 24 -rwxr-x---@ 1 dom 5000 106 13 Apr 12:09 app.yaml* drwxr-xr-x@ 12 dom 5000 408 13 Apr 12:43 dbindexer/ drwxr-xr-x@ 18 dom 5000 612 13 Apr 12:33 django/ drwxr-xr-x@ 23 dom 5000 782 13 Apr 12:43 djangoappengine/ drwxr-xr-x@ 15 dom 5000 510 13 Apr 12:43 djangotoolbox/ -rwxr-x--- 1 dom 5000 472 24 Mar 23:38 index.yaml* -rwxr-x--- 1 dom 5000 1002 24 Mar 23:38 main.py*
You’ll have to bundle all of this with your app. You may want to delete some bits of
django/contrib that you don’t use.
Now, how to get started with my app? I’ll need to create a django project. Normally I use the installed
django-admin.py. In this case, I’d like to use the version I’ve imported to my project.
% PYTHONPATH=. django/bin/django-admin.py Usage: django-admin.py subcommand [options] [args] … % PYTHONPATH=. django/bin/django-admin.py startproject hellodjango % mv hellodjango/* . %
So now how do I hook that up to
app.yaml? There’s no documentation, but there is a test app. And that contains the magic snippet:
handlers: - url: /.* script: djangoappengine/main/main.py
Now, how do I run this? The appengine launcher I’m using has a “play” button. My first attempt broke, because I’d made the app in the
hellodjango directory, the settings contained a reference to
hellodjango.urls, which should be just
urls. With that fixed, I get an “It worked!” page. Result!
dev_appserver.py approach (aka the play button) worked for me, but the djangoappengine docs say to use
./manage.py runserver, so I’ll do that.
Now, I have an empty app. Let’s add in a minimal hello world view. First, I create
from django.http import HttpResponse def home(request): return HttpResponse('<h1>Hello World</h1>')
And then adjust
urls.py to point to it.
from django.conf.urls.defaults import patterns, include, url import views urlpatterns = patterns('', url(r'^$', views.home, name='home'), )
I now see the Hello World! displayed in my browser. I’d like to get a nice template working. I’ll update my views to look like this:
from django.shortcuts import render def home(request): return render(request, 'home.html')
templates/home.html is as you would expect.
The final piece of the puzzle: how does django know where to find the template? In settings.py, there’s a TEMPLATE_DIRS setting.
TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__), 'templates'), )
At this point, you’re using regular django, and should be able to use the regular docs to carry on. Although, please read the list of djangoappengine caveats.
Web Frameworks Evening
On thursday, I attended the London Web Frameworks evening, basically because of the large london.pm contingent. There were three speakers for the evening: Matt Trout on Catalyst; Simon Willison showing off Django and Matt Biddulph exploring Rails. All this was happening in the large lecture theatre (really! That’s its name!) at the University of Westminster.
First up was Matt Trout. He pointed out that there are over 120 CPAN modules covering Catalyst, and only 25 minutes for the presentation, so he skipped a few. 🙂 Catalyst is billed as an “Elegant MVC web framework.” In practise, it seems to be somewhat Rails-like (it has the standalone web servers, the testing stuff and the generator scripts), apart from the fact that it’s more or less completely agnostic about the Model and View bits (and the environment in which it runs). And it likes plugins. A lot.
Again for authorization and authentication, there are plugins for pretty much anything that you would want: Databases, LDAP, PAM, Radius, Samba. The list goes on. Apparently, Catalyst has its own internal implementation of Roles and ACLs, but Matt didn’t go into much detail on that. When it comes to deployment, there are plugins for every option (Catalyst calls them Engines): Apache, Apache2, FastCGI, and a standalone server using HTTP::Daemon.
Probably the most important plugin mentioned was Config::YAML, which lets you configure the site using textual config files.
Other good points include the nice use of subroutine attributes and excellent testing support. And the packaging support making it very easy to distribute your applications.
Second was Simon Willison. Django is a relatively new Open Source project, but it’s been in development for about two years. It seems to be more designed around CMS needs, although it’s pretty flexible. Simon was a co-creator on his placement year. It was originally designed for running lawrence.com, an entertainment site for a small university town in Kansas.
Much of Django appears to have parallel evolution with Rails. They’re about the same age and they seem to have more-or-less independently arrived at the same solution.
Django philosophy: Less code; Loose coupling; Explicit over implicit (very pythonic); Consistency; Efficient SQL (raw SQL is encouraged where it provides benefits); Cool URLs.
Interestingly, Django implements its own ORM, instead of using something like SQLObject. As part of this, it does all the schema definition in Python, so it should be readily portable between databases. Apparently it already does the usual suspects: MySQL, PostgreSQL, SQLite.
One tiny feature which I really like is the ability to raise an HTTP status as an exception.
The templating language they use is something that was written specifically for Django. Apparently it was “inspired by Smarty” which in turn was inspired by Template Toolkit. How the wheels turn…
They have this feature called “Middleware”, which basically looks like stackable input/output filters.
The Django people are really big on getting the community involved in the design. They’ve already had a lot of translations and a large refactoring of the admin screens from the community. Because the deployment of Django is so small at this stage, they’re quite willing to break backwards compatibility if you can argue a good case.
Lastly, Matt Biddulph came up to talk about Rails. This was particularly interesting because unlike the other two people, he’s not a rails developer at all, he’s a rails user. And only for 3 months at that. This gave him a very good perspective on it, as opposed to “it’s all shiny!” He also acknowledged how good the Rails people are at marketing—nearly everybody in the audience knew something about it.
Rather than specific technical details, he talked more about the Rails philosophy. Stuff like “Convention over Configuration” and Rails being “Opinionated Software.” He came up with the phrase “The golden path”—which is how to develop in a Rails like manner. It’s possible to stray from it, but your life gets harder. Rails is very well integrated, with a clear direction.
Bits that he noted as being particularly useful: The Generators, which help point you in the right direction. The ease of Ajax integration. The really useful console and breakpointer scripts (which I wish I had in Perl for work).
He also outlined some good “Gotchas” for Rails. Stuff like the pluralisation sometimes being surprising—“try adding or removing an S if something doesn’t work.” The fact that Rails lazy loading can lead to some really inefficient SQL. Generally, Rails can be quite slow (compared to MySQL). And Ruby in the templates, which could end up being very chaotic (although he did point at Liquid as a new and better alternative).
Matt had a demo app with him—the BBC Programme Catalogue. This is a new interface to all the BBC’s programme metadata. The BBC librarians have been maintaining this enourmous amount of information for years, and it’s now getting a shiny new web frontend. Did you know it takes 8 hours for a single person to fill in the data for a single episode of Newsnight? Incredible. Anyway, he’s done an incredible job of getting all that data into Rails. The interface is still sucky, but will get a makeover before being released to the hounds^Wpublic early next year. I can’t wait to get my hands on that data.
After that, there was really only time for one question. Muttley piped up with “What do each one of you guys want to steal from each other?” Djangos admin screen’s were the main ones. Generally, they all feel that they would steal any useful features that they could from each other. Isn’t cross fertilisation great?
Unfortunately, I had to rush off afterwards to catch a train. Otherwise I would have enjoyed going to the pub with them all to talk over the bits some more. Anyway, my thanks to Dean Wilson for organising all this. Great to hear about things going on out there. See you all next weekend at the London Perl Workshop, I guess!