Some people states that using DB for storing images is not a good idea but that's no true. My advice is to use Django with AppEngine Blobstore Service in this way:
First, create a Django Custom Storage (or pick one from someone else like this one):
from django.core.files.storage import Storage
class AppEngineBlobStorage(Storage):
def exists(self, name):
...
def size(self, name):
...
def url(self, name):
...
def delete(self, name):
...
def listdir(self, path):
raise NotImplementedError()
This custom storage can receive Django images, convert them to Base64 strings and send them to your AppEngine Blobstore Service application (via xmlrpc for example).
Then, create a Django Image model:
from django.db import models
from django.db.models.fields.files import ImageField
from .storage import AppEngineBlobStorage
class Photo(models.Model):
caption = models.CharField(max_length=64, blank=True)
blob = ImageField(
upload_to='BlobStorage',
storage=AppEngineBlobStorage(),
max_length=255,
blank=False,
)
serving_url = models.URLField()
...
Then, you have to create an AppEngine application for receiving Django requests for storing images, transform Base64 strings to raw and store them in a Blob. For example:
# coding=utf-8
from __future__ import with_statement
import webapp2
from base64 import b64decode
from StringIO import StringIO
from xmlrpcserver import XmlRpcServer
from google.appengine.api import files
from google.appengine.api import images
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
class ImageRpcServer(object):
def upload(self, meta, photo, mime_type):
data = b64decode(photo)
file_name = files.blobstore.create(mime_type=mime_type)
with files.open(file_name, 'a') as f:
f.write(data)
files.finalize(file_name)
key = files.blobstore.get_blob_key(file_name)
return str(key)
def serving_url(self, meta, key):
return images.get_serving_url(blobstore.BlobKey(key))
...
Serving a blob
The key is the function get_serving_url. From Google docs:
If you are serving images, a more efficient and potentially
less-expensive method is to use get_serving_url using the App Engine
Images API rather than send_blob. The get_serving_url function lets
you serve the image directly, without having to go through your App
Engine instances.
Finally, by serving images with AppEngine, you can use the awesome feature of resize and crop images (check the documentation of get_serving_url
function), for example:
// Resize the image to 32 pixels (aspect-ratio preserved)
http://your_app_id.appspot.com/randomStringImageId=s32
Hope it helps. Good luck!