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.