2013-04-07 4 views
6

Mongoengineは、FileFieldとImageFieldをGridFSに格納します。元のファイル/イメージフィールドの機能を複製する最も簡単な方法は何ですか?Mongoengine FileFieldをディスクに保存していますか?

EDIT:

だから、これは私が現時点で所定の位置に持っていたクラスです。ファイルを読み込んでディスクに保存することができます.Mongoはファイルへのパスをデータベースに保持しています。

私はそれがproxy_classのオブジェクトを作成する必要があると信じているが、私が得ているすべてがパスになっている場合、どのように見えるのかわからないので(to_pythonに渡されるに)。

import os 
import datetime 

from mongoengine.python_support import str_types 
from django.db.models.fields.files import FieldFile 
from django.core.files.base import File 
from django.core.files.storage import default_storage 
from mongoengine.base import BaseField 
from mongoengine.connection import get_db, DEFAULT_CONNECTION_NAME 
from django.utils.encoding import force_text 
#from django.utils.encoding import force_str 


class DJFileField(BaseField): 

    proxy_class = FieldFile 

    def __init__(self, 
       db_alias=DEFAULT_CONNECTION_NAME, 
       name=None, 
       upload_to='', 
       storage=None, 
       **kwargs): 

     self.db_alias = db_alias 
     self.storage = storage or default_storage 
     self.upload_to = upload_to 

     if callable(upload_to): 
      self.generate_filename = upload_to 

     super(DJFileField, self).__init__(**kwargs) 


    def __get__(self, instance, owner): 
     # Lots of information on whats going on here can be found 
     # on Django's FieldFile implementation, go over to GitHub to 
     # read it. 
     file = instance._data.get(self.name) 

     if isinstance(file, str_types) or file is None: 
      attr = self.proxy_class(instance, self, file) 
      instance._data[self.name] = attr 

     elif isinstance(file, File) and not isinstance(file, FieldFile): 
      file_copy = self.proxy_class(instance, self, file.name) 
      file_copy.file = file 
      file_copy._committed = False 
      instance._data[self.name] = file_copy 

     elif isinstance(file, FieldFile) and not hasattr(file, 'field'): 
      file.instance = instance 
      file.field = self 
      file.storage = self.storage 

     # That was fun, wasn't it? 
     return instance._data[self.name] 


    def __set__(self, instance, value): 
     instance._data[self.name] = value 

    # The 3 methods below get used by the FieldFile proxy_object 
    def get_directory_name(self): 
     return os.path.normpath(force_text(datetime.datetime.now().strftime(self.upload_to))) 

    def get_filename(self, filename): 
     return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename))) 

    def generate_filename(self, instance, filename): 
     return os.path.join(self.get_directory_name(), self.get_filename(filename)) 


    def to_mongo(self, value): 
    # Store the path in MongoDB 
    # I also used this bit to actually save the file to disk. 
    # The value I'm getting here is a FileFiled and it all looks 
    # pretty good at this stage even though I'm not 100% sure 
    # of what's going on. 

     import ipdb; ipdb.set_trace() 

     if not value._committed and value is not None: 
      value.save(value.name, value) 
      return value.path 

     return value.path  


    def to_python(self, value): 
     # Now this is the real problem, value is the path that got saved 
     # in mongo. No idea how to return a FileField obj from here. 
     # self.instance and instance throw errors. 
+0

これは本当の質問ですか?あなたは、フィールドにしたいことを広げることができますか? – Ross

+0

Ross defは本当の質問です。私が意味することは、Djangoの元のFileFieldと基本的に同じように動作する、新しいFieldを作成したい場合、私は何をアドバイスしましたか?パス情報などのためだけにストレージオブジェクトとmongoを使用する。 – holografix

答えて

2

私はそれが良いほかになると思います - 多分それはより多くの枠組みにとらわれない作るためにLocalFileFieldと呼ばれ、あなたがテストやドキュメントを提供する場合、それはhttps://github.com/MongoEngine/extras-mongoengine

には絶好のに加え私は唯一の理由になるだろうコアでそれを持つことで販売されていない - あなたがレプリカセットを実行している場合でも、ファイルは1つのノードにしか保存されません。

+1

Rossに感謝します。私はどのようなテストを勧めましたか?いくつかの例を教えてもらえますか?私は敬意を表することに同意しない、私はそれがテンプレートに使用することができる文書に関連付けられた画像をアップロードする簡単な方法を見ることができないと私はそれがコアの一部でなければならないと思うと私は多くの開発者がそれをしたいと思います。または、私は何か明白なもの、すなわち:現在のMongoEngine.ImageFieldをテンプレート上で使用する方法を見落としています。 docsは、ローカルファイルシステムを使用する代わりに、S3のようなものを使用することを示唆することができます。 – holografix

関連する問題