سؤال

هل يمكن لأي شخص أن يوجهني إلى أي تطبيقات / تطبيقات Django توفر نظام تخزين مخصص قابل للتوجيه حتى أتمكن من استخدام Gridfs مع Django لتخزين تحميل الملفات؟

لقد وجدت DJango-MongoDB لكنها لا يبدو أنها تدعم Gridfs، ولا تقوم بتخزين Django.

أخطط لتشغيل MySQL لإعادة استخدام قاعدة البيانات العادية واستخدام MongoDB فقط لتخزين الملفات حتى أن أكون واضحا لا أريد استخدام MongoDB كقاعدة بيانات الرئيسية.

هل كانت مفيدة؟

المحلول

أعمل على Pymongo، برنامج تشغيل Mongodb Python، ولم أسمع بأي مشروع لتوفير تخزين مخصص ل Django باستخدام Gridfs. يبدو أن هذا يبدو أنه لن يكون من الصعب جدا الكتابة فوق Pymongo: ربما تكون ترجمة مباشرة لل Gridfs API. على Django تخزين API.. وبعد ربما يمكن أن نلقي نظرة على إلقاء شيء معا في مرحلة ما، ولكن سيكون هذا مشروع كبير مفتوح المصدر لأي شخص يتطلع إلى المشاركة.

نصائح أخرى

لقد نفذت مؤخرا دعم Gridfs في MongoEngine التي قد ترغب في الخروج. يتضمن ذلك خزانة تخزين Django التي يمكنك توصيلها مباشرة في مشاريع واستخدامها مع ImageField وما إلى ذلك، فأنا أستخدم هذه التقنيات في الإنتاج وتثبيتها كثيرا حتى الآن.

محرك django-mongodb قد تكون تستحق نظرة لأنها يمكنك من القيام بذلك دون الحاجة إلى إجراء تغييرات على رمز Django الحالي الخاص بك.

كنت بحاجة تماما ذلك ل مايان edms, ، تخزين وانفصال قاعدة البيانات. باستخدام أحدث مكتبة Pymongo's Michael Dirolf، كانت تافهة إلى حد ما للحصول على فئة أساسية تسير.

لتستخدمها:

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

ملف 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top