13

私は Django を使用して 1 つの Web サービスを作成していますが、その Web サービスが画像を返すようにしたいと考えています。Web サービスの基本アーキテクチャを決定しています。グーグルにつまずいた後、私が結論に達したのは次のとおりです。

  1. 画像を Base64 形式にエンコードした後、画像を DB に保存する必要があります。
  2. Bases64 でデコードされた文字列を直接送信すると、画像の転送が簡単になります。

しかし、Djangoモデルを使用してbases64でエンコードされた文字列をDBに保存するにはどうすればよいですか? また、私の基本的なアーキテクチャに欠陥がある場合は、私を導いてください。

Web サービスと Django は初めてです

ありがとう!!

4

4 に答える 4

12

画像の保存に DB を使用するのは得策ではないと言う人もいますが、それは正しくありません。私のアドバイスは、次のようにAppEngine Blobstore Serviceで Django を使用することです。

まず、Django カスタム ストレージを作成します (または、このような他の誰かから 1 つ選択します)。

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()

このカスタム ストレージは、Django 画像を受け取り、それらを Base64 文字列に変換して、AppEngine Blobstore Service アプリケーションに (たとえば xmlrpc 経由で) 送信できます。

次に、Django イメージ モデルを作成します。

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()
    ...

次に、画像を保存するための Django リクエストを受信するための AppEngine アプリケーションを作成し、Base64 文字列を raw に変換して Blob に保存する必要があります。例えば:

# 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))

      ...

ブロブの提供

重要なのは関数get_serving_urlです。Google ドキュメントから:

画像を配信する場合、send_blob ではなく、App Engine Images API を使用して get_serving_url を使用する方が効率的で、費用がかからない可能性があります。get_serving_url 関数を使用すると、App Engine インスタンスを介さずに画像を直接提供できます。

最後に、AppEngine で画像を提供することにより、画像のサイズ変更とトリミングの素晴らしい機能を使用できます (get_serving_url機能のドキュメントを確認してください)。例:

// 画像のサイズを 32 ピクセルに変更します (アスペクト比は維持されます) http://your_app_id.appspot.com/randomStringImageId=s32

それが役に立てば幸い。幸運を!

于 2013-09-13T04:37:42.553 に答える