2013-04-07 25 views
6

Mongoengine, FileField ve ImageField'ı GridFS'ye depolar. Orijinal Dosya/Görüntü Alanı'nın işlevselliğini çoğaltmanın en kolay yolu nedir?Mongoengine FileField diske kaydetme?

DÜZENLEME:

Yani şu anda ben bir yerde var sınıftır. Dosyaları yükleyebiliyorum ve diske kaydedebiliyorum, Mongo veritabanındaki dosyanın yolunu tutuyor.

Proxy_class'ın bir nesnesini oluşturması gerektiğine inandığım için "to_python" üzerine düşüyorum ama nasıl olduğunu göremiyorum, eğer dosya alıp aldığım bir yol (eğer değer geçtiyse) içinde). Bunun iyi bir ek olacağını düşünüyorum

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

Bu gerçek bir soru mu? Alanın yapmasını istediğin şeyi genişletebilir misin? – Ross

+0

Ross, gerçek bir soru. Demek istediğim: Django'daki orijinal FileField ile aynı şekilde davranan yeni bir Alana sahip olmak istediğimde ne yapmamı önerirsiniz. Bir depolama nesnesi ve mongoyu yalnızca yol bilgisi vb. Için kullanma. – holografix

cevap

2

- belki daha çerçeve agnostik yapmak için LocalFileField aradı ve testleri ve belgeler temin eğer https://github.com/MongoEngine/extras-mongoengine

Ben tek nedeni için büyük bir ek yapmak Çekirdeğe sahip olarak satılmadı - bir çoğaltıcı çalıştırıyorsanız, dosya hala yalnızca bir düğümde saklanırdı.

+1

Yanıt için teşekkürler Ross. Ne tür testler yaptın? Bana bazı örnekler verebilir misin? Saygılı bir şekilde katılmıyorum, bir şablon ile kullanılabilecek bir Belge ile ilişkili görüntüleri yüklemek için kolay bir yol göremediğimden ve bir çok devin bunu yapmak isteyebileceğini hayal ettiğimden, bunun çekirdeğin bir parçası olması gerektiğini düşünüyorum. Veya açık bir şey eksik mi, yani: bir şablon üzerinde geçerli MongoEngine.ImageField nasıl kullanılır. Dokümanlar, yerel bir dosya sistemi kullanmak yerine S3 gibi bir şey kullandığınızı söyleyebilir. – holografix