我正在尝试使用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项目。它有许多存储支持的选项,并且比我原来提出的解决方案更多的人使用。
答案 0 :(得分:8)
我认为你最好不要使用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_HOST
,GRIDFS_PORT
和GRIDFS_COLLECTION
可以在您的设置中定义,也可以作为host
,port
,collection
关键字参数传递给{您的模型GridFSStorage
中的{1}}。
我提到了Django的custom storage文件,并且松散地跟着this answer提到了类似的问题。