Pergunta

Pode alguém me aponte para quaisquer projectos / Django aplicativos que fornecem um sistema de armazenamento personalizado plugable para que eu possa usar GridFS com Django para o upload de arquivos loja?

Eu encontrei django-mongodb mas não parece GridFS de apoio, nem django-storages.

Eu pretendo executar mysql para os requrements banco de dados normais e única mongodb uso para armazenamento de arquivos de modo a ser claro que eu não quero usar o MongoDB como meu banco de dados principal.

Foi útil?

Solução

Eu trabalho em PyMongo, o motorista MongoDB Python, e não ouvi falar de nenhum projeto para fornecer armazenamento personalizado para Django usando GridFS. Isso parece que não seria muito difícil de escrever em cima de PyMongo: provavelmente poderia ser uma tradução direta do GridFS API para o API de armazenamento de Django. Talvez poderia dar uma olhada em jogar algo juntos em algum momento, mas isso seria um grande projeto de código aberto para quem quer se envolver.

Outras dicas

Recentemente implementou o GridFS apoiar em Mongoengine que você pôde gostar de checkout. Isso inclui um backend de armazenamento Django que você pode ligar para a direita em você projetos e uso com ImageField etc. Estou usando essas tecnologias na produção e está segurando muito bem até agora.

django-mongodb-motor pode valer a pena um olhar, pois permite você fazer isso sem a necessidade de fazer alterações ao seu código Django existente.

Eu precisava exatamente isso para maia EDMS , armazenamento plugable e separação de banco de dados. Usando mais recente biblioteca PyMongo de Michael Dirolf, foi bastante trivial para obter uma classe básica vai.

Para usá-lo:

from gridfsstorage import GridFSStorage
file = models.FileField(storage=GridFSStorage())

O arquivo gridfsstorage.py:

import os

from django.core.files.storage import Storage
from django.utils.encoding import force_unicode
from django.conf import settings

from pymongo import Connection
from gridfs import GridFS

class GridFSStorage(Storage):
    def __init__(self, *args, **kwargs):
        self.db = Connection(host=settings.GRIDFS_HOST,
            port=settings.GRIDFS_PORT)[settings.DATABASE_NAME]
        self.fs = GridFS(self.db)


    def save(self, name, content):
        while True:
            try:
                # This file has a file path that we can move.
                if hasattr(content, 'temporary_file_path'):
                    self.move(content.temporary_file_path(), name)
                    content.close()
                # This is a normal uploadedfile that we can stream.
                else:
                    # This fun binary flag incantation makes os.open throw an
                    # OSError if the file already exists before we open it.
                    newfile = self.fs.new_file(filename=name)
                    try:
                        for chunk in content.chunks():
                            newfile.write(chunk)
                    finally:
                        newfile.close()
        except Exception, e:
            raise
        else:
            # OK, the file save worked. Break out of the loop.
            break

        return name


    def open(self, name, *args, **kwars):
        return self.fs.get_last_version(name)


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


    def exists(self, name):
        return self.fs.exists(filename=name)        


    def path(self, name):
        return force_unicode(name)


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

    def move(self, old_file_name, name, chunk_size=1024*64):
        # first open the old file, so that it won't go away
        old_file = open(old_file_name, 'rb')
        try:
            newfile = self.fs.new_file(filename=name)

            try:
                current_chunk = None
                while current_chunk != '':
                    current_chunk = old_file.read(chunk_size)
                    newfile.write(current_chunk)
            finally:
                newfile.close()
        finally:
            old_file.close()

        try:
            os.remove(old_file_name)
        except OSError, e:
            # Certain operating systems (Cygwin and Windows) 
            # fail when deleting opened files, ignore it.  (For the 
            # systems where this happens, temporary files will be auto-deleted
            # on close anyway.)
            if getattr(e, 'winerror', 0) != 32 and getattr(e, 'errno', 0) != 13:
                raise
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top