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

发布于 2024-12-09 17:33:05 字数 349 浏览 0 评论 0原文

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

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

I've been searching for resources on how to integrate Amazon S3 with TinyMCE. The best link I've come up with so far is: http://forums.aurigma.com/yaf_postst4033_Amazon-S3-File-Manager-for-TinyMCE-and-CKEditor.aspx

Does anyone have any experience integrating this into a Django app? If not, what are some alternative solutions for rich text editing and pulling in images from S3?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

莫相离 2024-12-16 17:33:05

如果有人最近像我一样搜索了这个,并且需要一个解决方案来让 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 并设置按照此处中的说明设置媒体存储

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

DEFAULT_FILE_STORAGE = 'path.to.module.MediaStorage'

4) 在该模块内创建 MediaStorage 类使用以下 API 来使用 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

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

希望这会有所帮助

If someone has searched this recently as I have and needs a solution to get django-tinymce4-lite working with django-storages and django-filebrowser-no-grappelli, I've managed to get it working by doing the following:

1) Follow this excellent tutorial: https://karansthr.gitlab.io/fosstack/how-to-set-up-tinymce-in-django-app/

2) When it comes to getting the s3 part working you'll need to install django-storages and set up you mediastorages as described in the instructions here

3) You'll need to create a subclass of S3Boto3Storage and make that your DEFAULT_FILE_STORAGE as below:

DEFAULT_FILE_STORAGE = 'path.to.module.MediaStorage'

4) And inside that module create the MediaStorage class with the following API to work with 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

5) Make sure to put these in your Django Settings:

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

Hope this helps

一抹微笑 2024-12-16 17:33:05

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

I ended up using django-storages. Works perfectly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文