I am using Django for creating one Web service and I want that web service to return Images. I am deciding the basic architecture of my Web service. What I came up to conclusion after stumbling on google is:
But I have one issue how can I store bases64 encoded string in DB using Django models? Also, if you see any flaw in my basic architecture please guide me.
I am new to Web services and Django
Thanks!!
A database gives you the opportunity to store photos and other small images in a database table. You can create such a database table for example when you want to create an online photo album with descriptions of your photos. Storing images in a database table is not recommended.
Creating objects To create an object, instantiate it using keyword arguments to the model class, then call save() to save it to the database. This performs an INSERT SQL statement behind the scenes. Django doesn't hit the database until you explicitly call save() . The save() method has no return value.
In Django, a default database is automatically created for you. All you have to do is add the tables called models. The upload_to tells Django to store the photo in a directory called pics under the media directory. The list_display list tells Django admin to display its contents in the admin dashboard.
Generally databases are best for data and the file system is best for files. It depends what you're planning to do with the image though. If you're storing images for a web page then it's best to store them as a file on the server. The web server will very quickly find an image file and send it to a visitor.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With