【问题标题】:Django with Pluggable MongoDB Storage troubles带有可插拔 MongoDB 存储问题的 Django
【发布时间】:2011-06-29 20:16:27
【问题描述】:

我正在尝试使用 django 和 mongoengine 仅通过 GridFS 提供存储后端。我还有一个 MySQL 数据库。

当我从 django 管理员删除时遇到了一个奇怪的(对我来说)错误,我想知道我是否做错了什么。

我的代码如下所示:

# settings.py
from mongoengine import connect
connect("mongo_storage")

# models.py
from mongoengine.django.storage import GridFSStorage
class MyFile(models.Model):
    name = models.CharField(max_length=50)
    content = models.FileField(upload_to="appsfiles", storage=GridFSStorage())
    creation_time = models.DateTimeField(auto_now_add=True)
    last_update_time = models.DateTimeField(auto_now=True)

我可以很好地上传文件,但是当我删除它们时,似乎有些东西坏了,mongo 数据库似乎处于无法使用的状态,直到我手动删除所有 FileDocument.objects。发生这种情况时,我无法从 django 界面上传文件或删除它们。

从我的堆栈跟踪中:

/home/projects/vector/src/mongoengine/django/storage.py in _get_doc_with_name
        doc = [d for d in docs if getattr(d, self.field).name == name] ...
▼ Local vars
Variable    Value
_[1]    
[]
d   

docs    
Error in formatting: cannot set options after executing query
name    
u'testfile.pdf'
self    

/home/projects/vector/src/mongoengine/fields.py in __getattr__
        raise AttributeError 

我是否错误地使用了此功能?

更新:

感谢@zeekay 的回答,我能够让一个工作的gridfs 存储插件工作。我最终根本没有使用 mongoengine。我将修改后的解决方案放在github 上。有一个清晰的示例项目展示了如何使用它。我还把项目上传到pypi

另一个更新:

我强烈推荐django-storages 项目。它有很多支持存储的选项,并且比我最初提出的解决方案被更多的人使用。

【问题讨论】:

  • 我一直希望为工作中的玛雅link 安装做这样的事情。但我不知道如何解决您的问题。
  • 可能不是您想要的,但我为 Mayan link 添加了一个 GridFsStorage 后端。非常简单,只依赖于 Pymongo,您可以尝试将它用于您的应用程序。
  • 很酷,谢谢,我这个周末去看看

标签: django mongodb gridfs mongoengine


【解决方案1】:

我认为你最好不要为此使用 MongoEngine,我也没有太多运气。这是mongoengine.django.storage.GridFSStorage 的直接替代品,适用于管理员。

from django.core.files.storage import Storage
from django.conf import settings

from pymongo import Connection
from gridfs import GridFS

class GridFSStorage(Storage):
    def __init__(self, host='localhost', port=27017, collection='fs'):
        for s in ('host', 'port', 'collection'):
            name = 'GRIDFS_' + s.upper()
            if hasattr(settings, name):
                setattr(self, s, getattr(settings, name))
        for s, v in zip(('host', 'port', 'collection'), (host, port, collection)):
            if v:
                setattr(self, s, v)
        self.db = Connection(host=self.host, port=self.port)[self.collection]
        self.fs = GridFS(self.db)

    def _save(self, name, content):
        self.fs.put(content, filename=name)
        return name

    def _open(self, name, *args, **kwars):
        return self.fs.get_last_version(filename=name)

    def delete(self, name):
        oid = fs.get_last_version(filename=name)._id
        self.fs.delete(oid)

    def exists(self, name):
        return self.fs.exists({'filename': name})

    def size(self, name):
        return self.fs.get_last_version(filename=name).length

GRIDFS_HOSTGRIDFS_PORTGRIDFS_COLLECTION 可以在您的设置中定义或作为 hostportcollection 关键字参数传递给模型的GridFSStorage 中的GridFSStorage

我参考了 Django 的 custom storage 文档,并松散地跟着 this answer 回答了一个类似的问题。

【讨论】:

  • 太好了,谢谢!到目前为止,我还没有注意到这个解决方案有任何问题。您在 Github 或任何包含此项目的地方有项目吗?如果它易于找到和访问,它似乎可以很好地为社区服务。
  • 不行,我试试打包贴在pypi/github上!
  • 您好 Zeekay,我非常感谢您的工作让这件事朝着正确的方向发展。我在 github 上放置了一个项目,该项目使用了您的 storage.py 的修改版本,并有一个示例应用程序可以将其插入到工作中的 django 应用程序中:github.com/madisona/django-mongo-storage
  • @Aaron 干得好 :) 你也应该把它放在 pypi 上。可能应该将示例项目移动到示例子目录,并添加一个 setup.py 以便于安装。很棒的包装指南:guide.python-distribute.org.
  • 或者只是将它与 mongoengine (也在 GitHub 上)合并。我可能会在几天内完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-28
  • 1970-01-01
  • 1970-01-01
  • 2017-07-24
  • 1970-01-01
相关资源
最近更新 更多