Django с подключаемыми проблемами хранения MongoDB - PullRequest
28 голосов
/ 18 февраля 2011

Я пытаюсь использовать 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-хранилища проект.Он имеет множество опций хранения и используется гораздо большим количеством людей, чем мое первоначальное предлагаемое решение.

1 Ответ

8 голосов
/ 01 июня 2011

Я думаю, вам лучше не использовать 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 в FileField.

вашей модели. Я ссылался на документацию пользовательского хранилища Джанго и не очень следил за этим ответом к аналогичному вопросу.

...