GridFS 用のカスタム ストレージ システム (MongoDB)?
質問
Django で GridFS を使用してファイルのアップロードを保存できるように、プラグ可能なカスタム ストレージ システムを提供するプロジェクト/Django アプリを誰かが教えてもらえますか?
django-mongodb を見つけましたが、GridFS も django-storages もサポートしていないようです。
通常のデータベース要件には mysql を実行し、ファイルストレージには mongodb のみを使用する予定なので、明確にするために、メインデータベースとして mongodb を使用したくありません。
解決
私は MongoDB Python ドライバーである PyMongo に取り組んでいますが、GridFS を使用して Django にカスタム ストレージを提供するプロジェクトについては聞いたことがありません。これを PyMongo 上に記述するのはそれほど難しくないようです。おそらく直訳かもしれません グリッドFS API 上に Django ストレージ API. 。もしかしたら、いつか何かを一緒に作ることも考えられるかもしれませんが、これは参加したい人にとって素晴らしいオープンソース プロジェクトになるでしょう。
他のヒント
私は最近、<のhref = "http://schallis.com/2010/oct/18/so-gridfs-mongoengine--django-walk-into-a-bar-/" のrel = "nofollowを" を実装しました> GridFSあなたがチェックアウトしたいかもしれませんMongoengineするでサポート。これは、あなたが右のあなたのプロジェクトに差し込むと、私は生産にこれらの技術を使用していますし、それは今のところ大きなを保持してのImageFieldなどに使用することができますDjangoのストレージバックエンドが含まれてます。
ジャンゴ - MongoDBのエンジンには一見の価値があるかもしれませんもし既存のDjangoのコードに変更を加える必要なく、それをする。
私はまさにそのマヤEDMS に、プラグ可能なストレージとデータベースの分離のために必要。マイケル・ディロフの最新PyMongoライブラリを使用して、基本的なクラスが軌道に乗るために、むしろ些細だっます。
これを使用するには:
from gridfsstorage import GridFSStorage
file = models.FileField(storage=GridFSStorage())
gridfsstorage.pyファイルます:
import os
from django.core.files.storage import Storage
from django.utils.encoding import force_unicode
from django.conf import settings
from pymongo import Connection
from gridfs import GridFS
class GridFSStorage(Storage):
def __init__(self, *args, **kwargs):
self.db = Connection(host=settings.GRIDFS_HOST,
port=settings.GRIDFS_PORT)[settings.DATABASE_NAME]
self.fs = GridFS(self.db)
def save(self, name, content):
while True:
try:
# This file has a file path that we can move.
if hasattr(content, 'temporary_file_path'):
self.move(content.temporary_file_path(), name)
content.close()
# This is a normal uploadedfile that we can stream.
else:
# This fun binary flag incantation makes os.open throw an
# OSError if the file already exists before we open it.
newfile = self.fs.new_file(filename=name)
try:
for chunk in content.chunks():
newfile.write(chunk)
finally:
newfile.close()
except Exception, e:
raise
else:
# OK, the file save worked. Break out of the loop.
break
return name
def open(self, name, *args, **kwars):
return self.fs.get_last_version(name)
def delete(self, name):
oid = self.fs.get_last_version(name)._id
self.fs.delete(oid)
def exists(self, name):
return self.fs.exists(filename=name)
def path(self, name):
return force_unicode(name)
def size(self, name):
return self.fs.get_last_version(name).length
def move(self, old_file_name, name, chunk_size=1024*64):
# first open the old file, so that it won't go away
old_file = open(old_file_name, 'rb')
try:
newfile = self.fs.new_file(filename=name)
try:
current_chunk = None
while current_chunk != '':
current_chunk = old_file.read(chunk_size)
newfile.write(current_chunk)
finally:
newfile.close()
finally:
old_file.close()
try:
os.remove(old_file_name)
except OSError, e:
# Certain operating systems (Cygwin and Windows)
# fail when deleting opened files, ignore it. (For the
# systems where this happens, temporary files will be auto-deleted
# on close anyway.)
if getattr(e, 'winerror', 0) != 32 and getattr(e, 'errno', 0) != 13:
raise