Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
261 views
in Technique[技术] by (71.8m points)

python - Storing Images In DB Using Django Models

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:

  1. I should store Images in DB after encoding them to Base64 format.
  2. Transferring the Images would be easy when directly Bases64 decoded string is transmitted.

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!!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...