English ▼
Skip to page content Skip to main navigation
e.g. "templates" or "datastore"

# Using the Google App Engine Helper for Django

Matt Brown
May 2009

NOTE (Nov 2010): For existing Django apps, the App Engine team recommends a tool called Django-nonrel, a (currently) maintained fork of the latest version of Django which allows developers to run native Django applications (via Django's ORM) on traditional SQL databases as well as non-relational datastores (including App Engine's). (This differs from earlier projects like the Helper and the Patch which involve modification of your data model classes.) For more information on using Django-nonrel with App Engine, please see our Django-nonrel article which shows you how to convert a native App Engine webapp app to a pure Django app.

## Introduction

Google App Engine supports running any WSGI compliant application. Since Django supports this standard it is possible to build (or port existing) Django applications to run on Google App Engine.

This article will walk you through the process of starting a new Django project and getting it running on Google App Engine by reproducing the initial steps of creating the Polls application from the official Django tutorial. At each step the changes required for the App Engine environment are highlighted.

Before getting started you need to ensure that you have installed Python 2.5 and the Google App Engine SDK. The article also assumes you have previous experience with Django itself.

## Understanding the Google App Engine and Django Environments

The environment provided by Google App Engine differs from what a Django application expects in two major ways.

1. Google App Engine does not provide an SQL database so you cannot use Django's standard Model class.
2. Google App Engine restricts certain module imports and actions that Django tries to perform (such as creating and removing the test database).

We have created a helper that prevents you from needing to worry about most of these differences. The helper works by providing alternative implementations for the portions of Django that do not work with Google App Engine.

## Obtaining the Helper

The helper can be downloaded from the open source project at http://code.google.com/p/google-app-engine-django.

Download and extract the helper source archive into a directory called `mysite`

Within the directory you will see the standard Django project structure (`settings.py`, `urls.py`, etc) and a subdirectory (or application in Django terminology) named `appengine_django`. This is the helper that performs the work of integrating the Django and Google App Engine environments.

## Accessing the Google App Engine SDK

The helper needs access to the Google App Engine SDK. If you are running on Mac OS and you used the installer provided by Google you can proceed immediately to the next step (Verify your environment). The helper knows where the installer puts the SDK and automatically imports it from that location.

If you are running on Windows using the Google provided SDK installer you will need to install the Python for Windows extensions to enable automatic detection of the SDK.

Finally, if you are running on Linux, or you are running on Windows or Mac OS using the zipfile source distribution you will need to copy or link the extracted SDK to the `.google_appengine` directory (note the leading period, this is a hidden directory) within the `mysite` directory created above.

On Linux or Mac OS you can use a command like the following to achieve this. The command should be run from within the `mysite` directory.

    ln -s /path/to/google_appengine .google_appengine

## Install Django

The helper requires Django 1.0 or greater to function. The version of Django currently supplied with the Google App Engine SDK is only Django 0.96. This means you will need to bundle a copy of Django with your application.

The helper makes this easy by looking for Django within the top level application directory (`mysite`). The helper will first look for Django in a directory named `django` e.g. `mysite/django`. Alternatively, you can place a zipped copy of Django at `mysite/django.zip` which the helper will use if present. For details on how to create a suitable django.zip file you can refer to the Using Django 1.0 on App Engine with Zipimport article.

Note: We strongly recommend that you use Django 1.0 inside a zipfile as described above. If you prefer to stick with the 0.96 version of Django bundled in the SDK you can use an older (unsupported) version of the helper which you will find in the django096_compatible branch of the project SVN repository. This branch is unsupported and will not receive any further updates.

## Verify Your Environment

To verify that your environment is correctly setup you can start the server. Make sure you are in the `mysite` directory and type this command:

    python manage.py runserver

You will see output similar to the following

    INFO:root:Checking for updates to the SDK.
    INFO:root:The SDK is up to date.
    INFO:root:Running application appengine-django-example on port 8080: http://localhost:8080

You can safely ignore any lines beginning with `WARNING` that mention an inability to read datastore data, or problems with PIL. These simply warn you that there is not yet any data in your development datastore and that the Python imaging library is not installed on your computer. They will not prevent you from developing with the SDK and the helper.

Navigate to http://localhost:8080/ in your browser and you will see the standard Django welcome page. Behind the scenes the helper has overriden the default Django `runserver` command and replaced it with one that executes the `dev_appserver` provided by the Google App Engine SDK.

You can also run the Django test suite contained within the helper.

    python manage.py test

    .................................................
    ----------------------------------------------------------------------
    Ran 58 tests in 3.760s

## Changing the Application Name

Open `app.yaml` in your favorite editor and change the line named application to contain the name of your application. E.g:

    application: mysite

The helper needs this information to setup a unique development datastore on your computer for this project.

## Create a Django Application

Now you need to create a Django Application within your project to contain your models, views and tests. You can use the standard `manage.py startapp` command for this:

    python manage.py startapp polls

As expected that will create a directory polls which will contain:

    polls/
      __init__.py
      models.py
      views.py

### Create your Models

The polls app has two models: polls and choices. To create these models you need to use the Model class provided by the helper and the Google App Engine datastore properties. The standard Django Model and Property classes will not work. Although your models will not be using the Django model class the helper takes care of ensuring that they look like Django models and registers them with Django.

Edit the `polls/models.py` file so it looks like this:

    from appengine_django.models import BaseModel
    from google.appengine.ext import db

    class Poll(BaseModel):
        question = db.StringProperty()
        pub_date = db.DateTimeProperty('date published')

    class Choice(BaseModel):
        poll = db.ReferenceProperty(Poll)
        choice = db.StringProperty()
        votes = db.IntegerProperty()

### Activating Models

You do not need to explicitly create database tables for your models when using Google App Engine. The `sql*`, `syncdb` and `validate` commands are therefore superflous and the helper removes them from `manage.py` so you are not tempted to try and use them.

All you need to do to activate your models is edit `settings.py` and ensure that '`polls`' is listed in `INSTALLED_APPS`.

### Playing with the API

The helper module supports the interactive Python shell and ensures that it is setup to access the same development datastore that is used by the development appserver. You can access the Python shell using the familiar:

    python manage.py shell

The interactive Python shell is not restricted in the same way that code running under the appserver is.

### The Django Admin Site

The Django admin site is heavily tied to the concept of a SQL database and is not supported by Google App Engine. A replacement admin interface is provided automatically by the development appserver at `/_ah/admin` - eg, `http://localhost:8080/_ah/admin`.

### Views, Forms and URLs

URL configuration and view functions behave as normal when running within Google App Engine. As your models are not derived from the Django Model class you cannot use the Django Form class. Instead an App Engine compatible replacement is provided by the Google App Engine SDK at `google.appengine.ext.db.djangoforms`. The `djangoforms` module can also be used independently of a full Django project.

## Ongoing Development

From this point you should be able to continue development of your application using the techniques described above. The remainder of this article goes into more detail describing the implementation of the helper and some of the advanced features that it supports for testing your project and loading/dumping fixtures.

## Uploading Your Application

The helper adds a new command to allow you to upload your application in one easy step using the `update` option to `manage.py` as shown below:

    python manage.py update

This is equivalent to running the `appcfg.py` command from the Google App Engine SDK directly. You can also access the `rollback` and `vacuum_indexes` commands in the same way.

## Lauching the WSGI Handler

The `app.yaml` configuration file provided by the helper instructs the appserver to run `main.py` for all requests that are not static files. `main.py` contains code to take care of loading the helper and then launching the Django WSGI handler.

You can store you CSS, images, and other static content in my_application/static.

## Using the Database Backend with App Engine

The helper provides a fake database backend named 'appengine' that Django should be configured to use. This backend takes care of ensuring that the datastore is correctly initialised when running code outside of the appserver (eg. when using the interactive shell, running tests or loading and dumping fixtures).

You can clear the development datastore using the `reset` and `flush` commands to `manage.py`.

Note: The helper configures a separate datastore for each Django project that it is installed within. The path to the project specific datastore will be different from the default path used by the `dev_appserver.py` shipped in the Google App Engine SDK.

## Testing and Fixtures

As hinted in the previous paragraph the helper makes it possible to use the standard Django test infrastructure and to create fixtures containing data for your tests to manipulate.

Serialisation and Deserialisation of Models derived from the `BaseModel` class provided by the helper is supported for YAML, JSON and XML.

`ReferenceProperty` members of models are serialised using the `str()` representation of the `Key` associated with the model instance.

Tests and Fixtures can be manipulated using the standard `test`, `loaddata` and `dumpdata` commands to `manage.py`.

## Updating Django Settings

The helper module will automatically remove and modify settings that are not compatible with Google App Engine. To see the customisations from the default settings provided by Django run the diffsettings command. Eg:

    python manage.py diffsettings

    DATABASE_ENGINE = 'appengine'
    DEBUG = True
    INSTALLED_APPS = ['appengine_django']
    MIDDLEWARE_CLASSES = ()
    ROOT_URLCONF = 'urls'  ###
    SETTINGS_MODULE = 'mysite.settings'  ###
    SITE_ID = 1  ###
    TEMPLATE_DEBUG = True
    TIME_ZONE = 'UTC'

## Contributing

The provided helper module only scratches the surface of the possible integration between Django and the Google App Engine environment. If you have feature requests or extra code to contribute to the helper module please file a bug report on the project site at http://code.google.com/p/google-app-engine-django/issues/entry