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 main.py.

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.

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 main.py to your new directory:

# main.py import os, sys os.environ["DJANGO_SETTINGS_MODULE"] = "mashname.settings" sys.path.append("/home/brox/tmp/mashname") # 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. #django.dispatch.dispatcher.connect( # log_exception, django.core.signals.got_request_exception) # Unregister the rollback event handler. django.dispatch.dispatcher.disconnect( django.db._rollback_on_exception, django.core.signals.got_request_exception) def main(): # Create a Django application for WSGI. application = django.core.handlers.wsgi.WSGIHandler() # Run the WSGI CGI handler with that application. util.run_wsgi_app(application) if __name__ == "__main__": 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 handlers: - url: /.* script: main.py

Make sure to get the application name right.

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

tmp/mashname$ django-admin.py 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$ dev_appserver.py mashname INFO 2008-04-08 19:08:10,023 appcfg.py] Checking for updates to the SDK. INFO 2008-04-08 19:08:10,384 appcfg.py] The SDK is up to date. INFO 2008-04-08 19:08:10,404 dev_appserver_main.py] Running application mash name on port 8080: http://localhost:8080

Point your browser towards http://127.0.0.1:8080/ 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/manage.py 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/models.py so that it looks like this:

# models.py 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 views.py (in the same directory as models.py) so that it does what we want:

# views.py from django.http import HttpResponse from mashname.main.models import Visitor def main(request): visitor = Visitor() visitor.ip = request.META["REMOTE_ADDR"] visitor.put() result = "" visitors = Visitor.all() visitors.order("-added_on") 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 urls.py point towards the view:

# urls.py 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$ appcfg.py 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 http://mashname.appspot.com/.