【问题标题】:Mongoengine FileField saving to disk?Mongoengine FileField 保存到磁盘?
【发布时间】:2013-03-29 13:54:19
【问题描述】:

Mongoengine 将 FileField 和 ImageField 存储到 GridFS。复制原始文件/图像字段功能的最简单方法是什么?

编辑:

所以这是我目前的课程。我能够加载文件并将它们保存到磁盘,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.

【问题讨论】:

  • 这是一个真实的问题吗?您能详细说明您希望该领域做什么吗?
  • 罗斯定义了一个真正的问题。我的意思是:如果我想要一个新的 Field,你会建议我做什么,它的作用基本上与 Django 中的原始 FileField 相同。仅对路径信息等使用存储对象和 mongo。

标签: django mongodb pymongo mongoengine


【解决方案1】:

我认为这将是一个很好的补充 - 可能称为 LocalFileField 以使其与框架更加无关,如果您提供测试和文档,它将成为 https://github.com/MongoEngine/extras-mongoengine 的一个很好的补充

我不赞成将它放在核心中的唯一原因 - 如果您正在运行副本集,该文件仍将仅存储在一个节点上。

【讨论】:

  • 感谢罗斯的回复。你会推荐我做什么样的测试?你能给我一些例子吗?我非常不同意,我认为它应该是核心的一部分,因为我看不到一种简单的方法来上传与文档相关联的图像,然后可以在模板上使用,我想很多开发人员都希望这样做。或者我是否遗漏了一些明显的东西,即:如何在模板上使用当前的 MongoEngine.ImageField。文档可能会建议您使用 S3 之类的东西,而不是使用本地文件系统。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-01
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多