Django on Google App Engine in 13 simple steps

In this tutorial I will show you how to get a simple datastore-backed Django application up and running on the Google App Engine. I will assume that you are somewhat familiar with Django.

Update 1: You can download the full set of files from here. Make sure to fix the sys.path in

Update 2: There is now a Turkish translation of this tutorial, courtesy of Türker Sezer.

Update 3: Now in Russian as well.

Update 4: Brazilian Portuguese tranlation by Marcio Andrey Oliveira.

Step 1: Register an app name and install the development kit per the instructions.

Step 2: Create a directory for your application—for this tutorial my application is called mashname:

tmp$ mkdir mashname
tmp$ cd mashname

Step 3: Add a file called to your new directory:


import os, sys
os.environ["DJANGO_SETTINGS_MODULE"] = "mashname.settings"

# Google App Engine imports.
from google.appengine.ext.webapp import util

# Force Django to reload its settings.
from django.conf import settings
settings._target = None

import django.core.handlers.wsgi
import django.core.signals
import django.db
import django.dispatch.dispatcher

# Log errors.
#   log_exception, django.core.signals.got_request_exception)

# Unregister the rollback event handler.

def main():
    # Create a Django application for WSGI.
    application = django.core.handlers.wsgi.WSGIHandler()

    # Run the WSGI CGI handler with that application.

if __name__ == "__main__":

This is basically the same file as suggested here, except I had to set the Python path to be able to test locally. I also had to set the DJANGO_SETTINGS_MODULE—this might not be necessary when running on the App Engine. I had to disable the error logging which I was not able to get working.

Step 4: Add a file called app.yaml to the same directory:

application: mashname
version: 1
runtime: python
api_version: 1

- url: /.*

Make sure to get the application name right.

Step 5: From your mashname directory, create a new Django project:

tmp/mashname$ startproject mashname

(I’m assuming that your current Django setup is working as it should.)

Step 6: You should now be able to test your application:

tmp/mashname$ cd ..
tmp$ mashname
INFO     2008-04-08 19:08:10,023] Checking for updates to the SDK.
INFO     2008-04-08 19:08:10,384] The SDK is up to date.
INFO     2008-04-08 19:08:10,404] Running application mash
name on port 8080: http://localhost:8080

Point your browser towards and you should get the standard Django It worked! message.

Step 7: Create a Django app within the project:

tmp$ cd mashname
tmp/mashname$ python mashname/ startapp main

Step 8: Now it is time to add a model. We will be creating a simple application that logs all visitors to the data store and displays their IP address and time of visit. Edit ~/mashname/mashname/main/ so that it looks like this:


from google.appengine.ext import db

class Visitor(db.Model):
    ip = db.StringProperty()
    added_on = db.DateTimeProperty(auto_now_add=True)

There is no need to sync the database since we are not using regular Django models.

Step 9: Now we create a view that is responsible for both adding data to the Visitor model and showing the previous visitors. Edit (in the same directory as so that it does what we want:


from django.http import HttpResponse

from mashname.main.models import Visitor

def main(request):
    visitor = Visitor()
    visitor.ip = request.META["REMOTE_ADDR"]

    result = ""
    visitors = Visitor.all()

    for visitor in visitors.fetch(limit=40):
        result += visitor.ip + u" visited on " + unicode(visitor.added_on) + u""

    return HttpResponse(result)

Step 10: Finally, make your point towards the view:


from django.conf.urls.defaults import *

urlpatterns = patterns("",
    (r"^$", "mashname.main.views.main"),

Step 11: Test your application (as in step 6) and everything should hopefully work. For each page reload a new entry is added to the Visitor model and shown in the view.

Step 12: Upload your application to the Google App Engine:

tmp$ update mashname

For the first upload you will have to provide the mail address and password for your Google account.

Step 13: Enjoy! To view the final results, go to