• django-mdeditor支持七牛云存储图片


    由于django-mdeditor官方插件没有支持第三方存储,所以,我们只能进行修改源码的方式实现了。
    本次改写即使替换了其文件,不使用七牛云也是无关紧要的,因为在存储时,去settings.py中判断是否启用七牛云存储,只有配置了七牛云相关信息才会执行,否则还是原先的方式存储在本地。
    源文件路径venvLibsite-packagesmdeditorviews.py

    使用方法

    • 修改源文件
      源文件路径venvLibsite-packagesmdeditorviews.py 找到该文件,将下面的代码直接复制全文替换
    # -*- coding:utf-8 -*-
    import os
    import datetime
    
    
    from django.views import generic
    from django.conf import settings
    from django.http import JsonResponse
    from django.views.decorators.csrf import csrf_exempt
    from django.utils.decorators import method_decorator
    from .configs import MDConfig
    
    # TODO 此处获取default配置,当用户设置了其他配置时,此处无效,需要进一步完善
    MDEDITOR_CONFIGS = MDConfig('default')
    
    
    class UploadView(generic.View):
        """ upload image file """
    
        @method_decorator(csrf_exempt)
        def dispatch(self, *args, **kwargs):
            return super(UploadView, self).dispatch(*args, **kwargs)
    
        def post(self, request, *args, **kwargs):
            upload_image = request.FILES.get("editormd-image-file", None)
            media_root = settings.MEDIA_ROOT
    
            # image none check
            if not upload_image:
                return JsonResponse({
                    'success': 0,
                    'message': "未获取到要上传的图片",
                    'url': ""
                })
    
            # image format check
            file_name_list = upload_image.name.split('.')
            file_extension = file_name_list.pop(-1)
            file_name = '.'.join(file_name_list)
            if file_extension not in MDEDITOR_CONFIGS['upload_image_formats']:
                return JsonResponse({
                    'success': 0,
                    'message': "上传图片格式错误,允许上传图片格式为:%s" % ','.join(
                        MDEDITOR_CONFIGS['upload_image_formats']),
                    'url': ""
                })
    
            # image floder check
            file_path = os.path.join(media_root, MDEDITOR_CONFIGS['image_folder'])
            if not os.path.exists(file_path):
                try:
                    os.makedirs(file_path)
                except Exception as err:
                    return JsonResponse({
                        'success': 0,
                        'message': "上传失败:%s" % str(err),
                        'url': ""
                    })
    
            # save image
            try:
                use_qiniu = settings.MDEDITOR_USE_QINIU
                if use_qiniu:
                    import qiniu,shortuuid
                    from qiniu.http import ResponseInfo
                    from urllib import parse
                    qiniu_save = QiniuSave()
                    save_name,url = qiniu_save.save(file_extension,upload_image)
                    qiniu_save.dealwith_img(save_name)
                    qiniu_save.cdn_flush(save_name)
                else:
                    url = save_img_local(file_name, file_path, upload_image, file_extension)
            except AttributeError:
                url = save_img_local(file_name, file_path, upload_image, file_extension)
    
            return JsonResponse({'success': 1,
                                 'message': "上传成功!",
                                 'url': url})
    
        def save_img_local(self, file_name, file_path, upload_image, file_extension):
            '''将文件存储到本地'''
            file_full_name = '%s_%s.%s' % (file_name, '{0:%Y%m%d%H%M%S%f}'.format(datetime.datetime.now()),
                                           file_extension)
            with open(os.path.join(file_path, file_full_name), 'wb+') as file:
                for chunk in upload_image.chunks():
                    file.write(chunk)
            url = os.path.join(settings.MEDIA_URL, MDEDITOR_CONFIGS['image_folder'], file_full_name)
            return url
    
    class QiniuSave():
        def __init__(
                self,
                access_key=settings.QINIU_ACCESS_KEY,
                secret_key=settings.QINIU_SECRET_KEY,
                bucket_name=settings.QINIU_BUCKET_NAME,
                bucket_domain=settings.QINIU_BUCKET_DOMAIN,
                ):
            self.auth = qiniu.Auth(access_key, secret_key)
            self.bucket_name = bucket_name
            self.bucket_domain = bucket_domain
            self.bucket_manager = qiniu.BucketManager(self.auth)
            
        def re_name(self,file_extension):
            name = shortuuid.uuid() +'.'+ file_extension
            return name
    
    
        def save(self, file_extension, content):
    
            if hasattr(content, 'chunks'):
                content_str = b''.join(chunk for chunk in content.chunks())
            else:
                content_str = content.read()
            name = self.re_name(file_extension)
            self._put_file(name, content_str)
            url = parse.urljoin(self.bucket_domain, name)
            return name,url
    
        def _put_file(self, name, content):
            token = self.auth.upload_token(self.bucket_name)
            ret, info = qiniu.put_data(token, name, content)
            if ret is None or ret['key'] != name:
                raise QiniuError(info)
    
        # 将上传处理后的图片刷新到cdn节点,减少回源流量
        def cdn_flush(self,key):
            cdn_manager = qiniu.CdnManager(self.auth)
            domine = self.bucket_name
            need_flush_url = domine + key
            # 需要刷新的文件链接
            urls = [
                need_flush_url,
            ]
            # URL刷新链接
            refresh_url_result = cdn_manager.refresh_urls(urls)
            return
    
        # 进行上传的图片处理
        def dealwith_img(self,key):
            q = self.auth
            bucket_name = self.bucket_name
            # pipeline是使用的队列名称,不设置代表不使用私有队列,使用公有队列。
            # pipeline = 'your_pipeline'
            # 要进行的转换格式操作。
            # fops = 'imageView2/0/format/webp/interlace/1'
            fops = 'imageMogr2/format/webp'
            # 可以对缩略后的文件进行使用saveas参数自定义命名,当然也可以不指定文件会默认命名并保存在当前空间
            saveas_key = qiniu.urlsafe_base64_encode(bucket_name + ':' + key)
            fops = fops + '|saveas/' + saveas_key
            # pfop = qiniu.PersistentFop(q, bucket_name, pipeline)
            pfop = qiniu.PersistentFop(q, bucket_name)
            ops = []
            ops.append(fops)
            ret, info = pfop.execute(key, ops, 1)
            assert ret['persistentId'] is not None
            return
    
    
    
    class QiniuError(IOError):
    
        def __init__(self, value):
            if isinstance("Debuf Info", ResponseInfo):
                super(QiniuError, self).__init__(
                    "Qiniu Response Info %s" % value
                )
            else:
                super(QiniuError, self).__init__(value)
    
    
    • 在django的settings.py中配置
    # mdeitor配置
    MDEDITOR_USE_QINIU = True
    # qiniuyun
    
    QINIU_ACCESS_KEY = '七牛云账号的access_key'
    QINIU_SECRET_KEY = '七牛云账号的secret_key'
    QINIU_BUCKET_NAME = '七牛云的空间名称'
    QINIU_BUCKET_DOMAIN = '七牛云空间绑定的自定义的cdn加速域名,格式:http://example.com或者:https://example.com'
    
  • 相关阅读:
    .net程序员书单
    脱敏小软件
    .NET处理HTTP请求
    WPF 按名称查找控件
    软件工程现行国标汇集
    企业应用架构模式读书笔记 第一章 分层
    mysql远程访问
    知道二叉树的先序和中序遍历,重建该二叉树
    微信小程序地图模块
    微信小程序蓝牙模块
  • 原文地址:https://www.cnblogs.com/xshan/p/14212025.html
Copyright © 2020-2023  润新知