Tips and Tricks for Django on Google App Engine

Recently I was tasked with creating a dajngo app which runs on Google App Engine (GAE). Now anyone familiar with GAE knows that they don’t fully support relational/SQL storage just yet (Google Cloud SQL is in an experimental phase at this time). Instead they have something called App Engine Datastore which is a schemaless object storage (NoSQL of sorts). So to get django to play nice with this storage, good people at ABP created a fork - django-nonrel which runs seamlessly out of the box on GAE. Easy enough.

Although there were couple of things which I tried to do that were not so straight forward. I’m just going to document those here in hopes that someone will find it useful.

Uploading Images

First up, how about uploading images?

Well in that case you’ll have to install the following libraries:

django-filetransfers - It’s an abstraction layer which allows for uploads into remote datastores, like AppEngine or S3 using django’s standard models.FileField

But what if you wanted to use models.ImageField instead of models.FileField? Since ImageField depends on PIL which is not available on GAE, it won’t work out of the box. You will need to install a mock PIL class library which handles the 3 functions necessary for the ImageField to validate: open(), read(), and verify().

Next up, what if you wanted to upload images through django admin? Well in most likelihood you probably encountered an error like this while trying to do so:

ValueError: The App Engine storage backend only supports BlobstoreFile instances or File instances whose file attribute is a BlobstoreFile.

Luckily I found a fork of the filetransfers library here which adds support for the admin. So instead of using the original package, just use the fork. Then all you have to do is, inherit the admin class from FiletransferAdmin in your admin.py:

from filetransfers.admin import FiletransferAdmin
from myapp.models import MyModel

class MyModelAdmin(FiletransferAdmin):    
    pass

admin.site.register(MyModel, MyModelAdmin)

Volia! That’s all you need to do to get image uploads working correctly using django-nonrel admin on GAE!

Search

Due to the NoSql nature of the GAE storage some of the things you would expect like case-insensitive queries (iexact, istartswith, etc.), JOINs, etc. won’t work as expected. ABP strikes once again with dbindexer which abstracts away most of those differences and lets you use some of that functionality just like how you would in regular django. Also, if you are looking for full-text search support, there’s a great package for that as well - nonreal-search

Also keep in mind that ABP no longer supports or maintains any of these libraries so it’s best to get the latest source from the official Github account - https://github.com/django-nonrel

Hopefully in the future all this wont be necessary as GAE support for django becomes more robust. Although you can still give it a spin while its still experimental: https://developers.google.com/appengine/docs/python/cloud-sql/django

Happy hacking!

If you liked this post, 🗞 subscribe to my newsletter and follow me on 𝕏!