Mongoengine將FileField和ImageField存儲到GridFS。什麼是最簡單的方法來複制原始文件/圖像領域的功能?編輯:Mongoengine FileField保存到磁盤?
所以這是我現在的班級。我可以加載文件並將其保存到磁盤,Mongo保存數據庫中文件的路徑。
我摔倒在「to_python」,因爲我認爲它需要創建一個proxy_class的對象,但我不明白如何,如果我所得到的是文件的路徑(作爲值傳遞在)。
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.
這是一個真正的問題嗎?你能擴展你想要的領域嗎? – Ross 2013-04-10 11:38:35
羅斯確定了一個真正的問題。我的意思是:如果我想要一個新的Field,它基本上與Django中的原始FileField的行爲方式相同,您會建議我做什麼。使用存儲對象和mongo僅用於路徑信息等。 – holografix 2013-04-11 02:05:56