使用 Django 模型在数据库中存储图像

新手上路,请多包涵

我正在使用 Django 创建一个 Web 服务,我希望该 Web 服务返回图像。我正在决定我的 Web 服务的基本架构。在谷歌上绊倒后我得出的结论是:

  1. 在将图像编码为 Base64 格式后,我应该将图像存储在数据库中。
  2. 当直接传输 Bases64 解码字符串时,传输图像会很容易。

但我有一个问题,如何使用 Django 模型将 base64 编码的字符串存储在数据库中?另外,如果您发现我的基本架构有任何缺陷,请指导我。

我是 Web 服务和 Django 的新手

谢谢!!

原文由 Mayank Jain 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 433
1 个回答

有些人说使用 DB 存储图像不是一个好主意,但事实并非如此。我的建议是以这种方式将 Django 与 AppEngine Blobstore 服务 一起使用:

首先,创建一个 Django 自定义存储(或者像 这样从别人那里挑选一个):

 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 服务应用程序(例如通过 xmlrpc)。

然后,创建一个 Django Image 模型:

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

然后,您必须创建一个 AppEngine 应用程序来接收存储图像的 Django 请求,将 Base64 字符串转换为原始字符串并将它们存储在 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))

      ...

提供一个 blob

关键是函数 get_serving_url 。来自谷歌文档:

如果您提供图像服务,一种更有效且成本可能更低的方法是使用 App Engine Images API 而不是 send_blob 来使用 get_serving_url。 get_serving_url 函数让您可以直接提供图像,而无需通过您的 App Engine 实例。

最后,通过使用 AppEngine 提供图像,您可以使用调整大小和裁剪图像的强大功能(查看 get_serving_url 函数的文档),例如:

// 将图像调整为 32 像素(保留宽高比) http://your_app_id.appspot.com/randomStringImageId=s32

希望能帮助到你。祝你好运!

原文由 Cartucho 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题