将 S3 上传/浏览与 django-tinymce 集成

Bra*_*don 5 django tinymce amazon-s3

我一直在寻找有关如何将 Amazon S3 与 TinyMCE 集成的资源。到目前为止,我想到的最好的链接是:http://forums.aurigma.com/yaf_postst4033_Amazon-S3-File-Manager-for-TinyMCE-and-CKEditor.aspx

有人有将其集成到 Django 应用程序中的经验吗?如果没有,有哪些用于富文本编辑和从 S3 提取图像的替代解决方案?

Oma*_*mar 9

如果有人最近像我一样搜索过这个问题,并且需要一个解决方案来让 django-tinymce4-lite 与 django-storages 和 django-filebrowser-no-grappelli 一起工作,我已经通过执行以下操作设法让它工作:

1)遵循这个优秀的教程:https://karansthr.gitlab.io/fosstack/how-to-set-up-tinymce-in-django-app/

2) 当涉及到让 s3 部分工作时,您需要安装 django-storages 并按照此处的说明中所述设置 mediastorages

3)您需要创建 S3Boto3Storage 的子类并将其设置DEFAULT_FILE_STORAGE为如下:

DEFAULT_FILE_STORAGE = 'path.to.module.MediaStorage'
Run Code Online (Sandbox Code Playgroud)

4) 在该模块内使用以下 API 创建 MediaStorage 类以与 FileBrowser 一起使用

class MediaStorage(S3Boto3Storage):
    location = settings.MEDIAFILES_LOCATION
    isfilecached = {}

    def isdir(self, name):
        if not name:  # Empty name is a directory
            return True

        if self.isfile(name):
            return False

        return True

    def isfile(self, name):
        if len(name.split('.')) > 1:
            return True
        try:
            name = self._normalize_name(self._clean_name(name))
            if self.isfilecached.get(name) is not None:
                return self.isfilecached.get(name)

            f = S3Boto3StorageFile(name, 'rb', self)
            if "directory" in f.obj.content_type:
                isfile = False
            else:
                isfile = True
        except Exception:
            isfile = False
        self.isfilecached[name] = isfile
        return isfile

    def move(self, old_file_name, new_file_name, allow_overwrite=False):

        if self.exists(new_file_name):
            if allow_overwrite:
                self.delete(new_file_name)
            else:
                raise "The destination file '%s' exists and allow_overwrite is False" % new_file_name

        old_key_name = self._encode_name(self._normalize_name(self._clean_name(old_file_name)))
        new_key_name = self._encode_name(self._normalize_name(self._clean_name(new_file_name)))

        k = self.bucket.meta.client.copy(
            {
                'Bucket': self.bucket.name,
                'Key': new_key_name
            },
            self.bucket.name,
            old_key_name
        )

        if not k:
            raise "Couldn't copy '%s' to '%s'" % (old_file_name, new_file_name)

        self.delete(old_file_name)

    def makedirs(self, name):
        name = self._normalize_name(self._clean_name(name))
        return self.bucket.meta.client.put_object(Bucket=self.bucket.name, Key=f'{name}/')

    def rmtree(self, name):
        name = self._normalize_name(self._clean_name(name))
        delete_objects = [{'Key': f"{name}/"}]

        dirlist = self.listdir(self._encode_name(name))
        for item in dirlist:
            for obj in item:
                obj_name = f"{name}/{obj}"
                if self.isdir(obj_name):
                    obj_name = f"{obj_name}/"
                delete_objects.append({'Key': obj_name})
        self.bucket.delete_objects(Delete={'Objects': delete_objects})

    def path(self, name):
        return name

    def listdir(self, name):
        directories, files = super().listdir(name)
        if '.' in files:
            files.remove('.')
        return directories, files

    def exists(self, name):
        if self.isdir(name):
            return True
        else:
            return super().exists(name)

    def get_modified_time(self, name):
        try:
            # S3 boto3 library requires that directorys have the trailing slash
            if self.isdir(name):
                name = f'{name}/'
            modified_date = super().get_modified_time(name)
        except Exception:
            modified_date = timezone.now()
        return modified_date

    def size(self, name):
        try:
            # S3 boto3 library requires that directorys have the trailing slash
            if self.isdir(name):
                name = f'{name}/'
            size = super().size(name)
        except Exception:
            size = 0
        return size
Run Code Online (Sandbox Code Playgroud)

5) 确保将这些放入您的 Django 设置中:

MEDIAFILES_LOCATION = 'media'
DEFAULT_FILE_STORAGE = 'path.to.module.MediaStorage'

FILEBROWSER_DEFAULT_PERMISSIONS = None
FILEBROWSER_LIST_PER_PAGE = 5  # Speeds up the load of the filebrowser files

AWS_PRELOAD_METADATA = True     # Speeds up the load of the filebrowser files
AWS_QUERYSTRING_AUTH = False    # Speeds up the load of the filebrowser files
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助


Bra*_*don 0

我最终使用了django-storages。工作完美。