• python3、Django中使用Uediter百度富文本编辑器的配置方法


    环境:Django==2.0.2 

       python == 3.7.3

    为什么要说明环境?因为python3.7后会有路由配置, 文件读取等问题

    参考文档:Django集成百度富文本编辑器uediter

    首先从ueEditor官网下载最新版本的包,目前官网上提供了ASP、.NET、PHP、JSP版本的,django版本只有一个第三方个人开发的,但看上出配置起来稍微复杂一点.

    目前相对复杂的的就是文件图片上传的配置问题,接下来主要说明此问题,先看几个文件作用:

    ueditor.all.js  ---   ueditor的入口,用于初始化插件等作用

    ueditor.config.js   ---  ueditor完整配置项

    controller.jsp      ----   相当于是一个action方法,用于请求返回config.json 文件,这个主要就是文件上传的控制后台,与其他语言的区别也就是在此,主要重写此文件。

    config.json        -----   上传等功能都是在这个文件里配置

    uEditor与后台交互的逻辑:

    1.编辑器初始化时,异步请求后台处理页面,处理程序应该返回一套json格式的配置信息,请求地址携带的参数为action=config

    2.点击图片上传按钮,异步请求后台处理页面,请求地址携带参数为action=uploadimage

    3.点击视频上传按钮,异步请求后台处理页面,请求地址携带参数为action=uploadvideo

    4.点击附件上传按钮,异步请求后台处理页面,请求地址携带参数为action=uploadfile

    5.点击多图上传中的在线图片选项卡,异步请求后台处理页面,请求地址携带参数为action=listimage

    6.点击附件上传的在线文件选项卡,异步请求后台处理页面,请求地址携带参数为action=listfile

    7.点击涂鸦按钮后,异步请求后台处理页面,请求地址携带参数为action=uploadscrawl

    主要步骤:

    一、下载uediter,我这里下载的是php版本的,将其放置在项目的某一位置,我这里放在/static/js/base/plugins/下,并在项目下的url.py中配置uediter所在目录的静态文件路径:

    from django.views.static import serve
    path('ue/(?P.*)', serve, {'document_root': os.path.dirname(__file__).replace('\', '/') + "/static/js/base/plugins/uediter"}),  # uediter

    二、在根目录下新建ueconfig.json文件,配置以下信息:

    {"imageActionName": "uploadimage", 
        "imageFieldName": "upfile", 
        "imageMaxSize": 2048000, 
        "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"],
        "imageCompressEnable": true, 
        "imageCompressBorder": 1600, 
        "imageInsertAlign": "none", 
        "imageUrlPrefix": "/static/upload/image/",
        "imagePathFormat": "image/{yyyy}{mm}{dd}/{time}{rand:6}", 
    
        "scrawlActionName": "uploadscrawl",
        "scrawlFieldName": "upfile", 
        "scrawlPathFormat": "/images/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}",
        "scrawlMaxSize": 2048000, 
        "scrawlUrlPrefix": "/static/upload/image/",
        "scrawlInsertAlign": "none",
    
        "snapscreenActionName": "uploadimage", 
        "snapscreenPathFormat": "/images/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", 
        "snapscreenUrlPrefix": "//static/upload/image/",
        "snapscreenInsertAlign": "none", 
    
        "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
        "catcherActionName": "catchimage", 
        "catcherFieldName": "source", 
        "catcherPathFormat": "/images/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", 
        "catcherUrlPrefix": "/static/upload/image/",
        "catcherMaxSize": 2048000, 
        "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], 
    
        "videoActionName": "uploadvideo", 
        "videoFieldName": "upfile", 
        "videoPathFormat": "upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", 
        "videoUrlPrefix": "/static/upload/image/",
        "videoMaxSize": 102400000, 
        "videoAllowFiles": [
            ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
            ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], 
    
        "fileActionName": "uploadfile", 
        "fileFieldName": "upfile", 
        "filePathFormat": "file/{yyyy}{mm}{dd}/{time}{rand:6}", 
        "fileUrlPrefix": "/static/upload/image/",
        "fileMaxSize": 51200000,
        "fileAllowFiles": [
            ".png", ".jpg", ".jpeg", ".gif", ".bmp",
            ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
            ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
            ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
            ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
        ], 
    
        "imageManagerActionName": "listimage", 
        "imageManagerListPath": "/upload/onlineimages/", 
        "imageManagerListSize": 20, 
        "imageManagerUrlPrefix": "/static/upload/image/",
        "imageManagerInsertAlign": "none",
        "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], 
    
        "fileManagerActionName": "listfile", 
        "fileManagerListPath": "/upload/onlinefiles/", 
        "fileManagerUrlPrefix": "/static/upload/image/",
        "fileManagerListSize": 20, 
        "fileManagerAllowFiles": [
            ".png", ".jpg", ".jpeg", ".gif", ".bmp",
            ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
            ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
            ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
            ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
        ] 
    }
    ueconfig.json

    注意修改几处关键路径信息:

    "imageUrlPrefix": "/upload/images/"修改为自己项目中图片上传后保存的位置,demo中是/upload/images/这个目录    
    "scrawlUrlPrefix": "/upload/images/", 修改为自己项目中涂鸦     
    "snapscreenUrlPrefix": "/upload/images/", 截图保存位置     
    "catcherUrlPrefix": "/upload/images/", 网络图片保存位置     
    "videoUrlPrefix": "/upload/vedio/"   视频文件保存地址    
     "fileUrlPrefix": "/upload/files/" 附件保存地址     
    "imageManagerUrlPrefix": "/upload/onlineimages/", 在线图片所在位置,在线图片实际就是服务器为用户提供的可选图片    
     "fileManagerUrlPrefix": "/upload/onlinefiles/"  在线附件所在位置,在线附件实际就是服务器为用户提供的可选附件

    三、设置上面的ueconfig.json文件的所在目录的静态路径,在项目下的url.py中:

    from django.views.static import serve 
    path('upload/(?P.*)', serve, {'document_root': (os.path.dirname(__file__)+"/static/upload").replace('\','/') }),  # 上传文件

    四、需要确保ueconfig.json中的路径文件存在,images、vedio、 files、onlinefiles、onlineimages几个子目录

    五、设置controller.py文件,这个文件主要是加载uediter的时候,异步请求视图函数

    # -*- coding:utf-8 -*-
    
    from django.http import HttpResponse
    import codecs
    import json
    import os
    from django.views.decorators.csrf import csrf_exempt
    import random
    from datetime import *
    from BJJT.settings import BASE_DIR
    
    ROOT = BASE_DIR
    
    
    # 本地上传图片时构造json返回值
    class JsonResult(object):
        def __init__(self, state="未知错误", url="", title="", original="", error="null"):
            super(JsonResult, self).__init__()
            self.state = state
            self.url = url
            self.title = title
            self.original = original
            self.error = error
    
    
    # 构造返回json
    def buildJsonResult(result):
        jsondata = {"state": result.state, "url": result.url, "title": result.title, "original": result.original,
                    "error": result.error}
        return json.dumps(jsondata)
    
    
    def buildFileName(filename):
        dt = datetime.now()
        name, ext = os.path.splitext(filename)
        return dt.strftime("%Y%m%d%M%H%S{0}{1}".format(random.randint(1, 999999), ext))
    
    
    # 读取json文件
    def getConfigContent():
        # jsonfile = file(ROOT + "/ueconfig.json")
        jsonfile = os.path.join(ROOT + "/BJJT/ueconfig.json")
        with open(jsonfile, 'r', encoding='utf8') as f:
            content = json.load(f)
        return content
    
    
    # 上传配置类
    class UploadConfig(object):
        def __init__(self, PathFormat, UploadFieldName, SizeLimit, AllowExtensions, SavePath, Base64, Base64Filename):
            super(UploadConfig, self).__init__()
            self.PathFormat = PathFormat
            self.UploadFieldName = UploadFieldName
            self.SizeLimit = SizeLimit
            self.AllowExtensions = AllowExtensions
            self.SavePath = SavePath
            self.Base64 = Base64
            self.Base64Filename = Base64Filename
    
    
    # 获取json配置中的某属性值
    def GetConfigValue(key):
        config = getConfigContent()
        return config[key]
    
    
    # 检查文件扩展名是否在允许的扩展名内
    def CheckFileType(filename, AllowExtensions):
        exts = list(AllowExtensions)
        name, ext = os.path.splitext(filename)
        return ext in exts
    
    
    def CheckFileSize(filesize, SizeLimit):
        return filesize < SizeLimit
    
    
    # 处理上传图片、文件、视频文件
    @csrf_exempt
    def uploadFile(request, config):
        result = JsonResult()
        if config.Base64:
            pass
        else:
            buf = request.FILES.get(config.UploadFieldName)
            filename = buf.name
            if not CheckFileType(filename, config.AllowExtensions):
                result.error = u"不允许的文件格式"
                return HttpResponse(buildJsonResult(result))
    
            if not CheckFileSize(buf.size, config.SizeLimit):
                result.error = u"文件大小超出服务器限制"
                return HttpResponse(buildJsonResult(result))
    
            try:
                truelyName = buildFileName(filename)
                webUrl = config.SavePath + truelyName
                savePath = ROOT + webUrl
                with open(savePath, "wb") as f:
                    for chunk in buf:
                        f.write(chunk)
                result.state = "SUCCESS"
                result.url = truelyName
                result.title = truelyName
                result.original = truelyName
                response = HttpResponse(buildJsonResult(result))
                response["Content-Type"] = "text/plain"
                return response
            except Exception as e:
                print(e)
                result.error = u"网络错误"
                return HttpResponse(buildJsonResult(result))
    
    
    # 处理在线图片与在线文件
    # 返回的数据格式:{"state":"SUCCESS","list":[{"url":"upload/image/20140627/6353948647502438222009315.png"},{"url":"upload/image/20140627/6353948659383617789875352.png"},{"url":"upload/image/20140701/6353980733328090063690725.png"},{"url":"upload/image/20140701/6353980745691597223366891.png"},{"url":"upload/image/20140701/6353980747586705613811538.png"},{"url":"upload/image/20140701/6353980823509548151892908.png"}],"start":0,"size":20,"total":6}
    def listFileManage(request, imageManagerListPath, imageManagerAllowFiles, listsize):
        pstart = request.GET.get("start")
        start = pstart == None and int(pstart) or 0
        psize = request.GET.get("size")
        size = psize == None and int(GetConfigValue(listsize)) or int(psize)
        localPath = ROOT + imageManagerListPath
        filelist = []
        exts = list(imageManagerAllowFiles)
        index = start
        for imagename in os.listdir(localPath):
            name, ext = os.path.splitext(imagename)
            if ext in exts:
                filelist.append(dict(url=imagename))
                index += 1
                if index - start >= size:
                    break
        jsondata = {"state": "SUCCESS", "list": filelist, "start": start, "size": size, "total": index}
        return HttpResponse(json.dumps(jsondata))
    
    
    # 返回配置信息
    def configHandler(request):
        content = getConfigContent()
        callback = request.GET.get("callback")
        if callback:
            return HttpResponse("{0}{1}".format(callback, json.dumps(content)))
        return HttpResponse(json.dumps(content))
    
    
    # 图片上传控制
    @csrf_exempt
    def uploadimageHandler(request):
        AllowExtensions = GetConfigValue("imageAllowFiles")
        PathFormat = GetConfigValue("imagePathFormat")
        SizeLimit = GetConfigValue("imageMaxSize")
        UploadFieldName = GetConfigValue("imageFieldName")
        SavePath = GetConfigValue("imageUrlPrefix")
        upconfig = UploadConfig(PathFormat, UploadFieldName, SizeLimit, AllowExtensions, SavePath, False, '')
        return uploadFile(request, upconfig)
    
    
    def uploadvideoHandler(request):
        AllowExtensions = GetConfigValue("videoAllowFiles")
        PathFormat = GetConfigValue("videoPathFormat")
        SizeLimit = GetConfigValue("videoMaxSize")
        UploadFieldName = GetConfigValue("videoFieldName")
        SavePath = GetConfigValue("videoUrlPrefix")
        upconfig = UploadConfig(PathFormat, UploadFieldName, SizeLimit, AllowExtensions, SavePath, False, '')
        return uploadFile(request, upconfig)
    
    
    def uploadfileHandler(request):
        AllowExtensions = GetConfigValue("fileAllowFiles")
        PathFormat = GetConfigValue("filePathFormat")
        SizeLimit = GetConfigValue("fileMaxSize")
        UploadFieldName = GetConfigValue("fileFieldName")
        SavePath = GetConfigValue("fileUrlPrefix")
        upconfig = UploadConfig(PathFormat, UploadFieldName, SizeLimit, AllowExtensions, SavePath, False, '')
        return uploadFile(request, upconfig)
    
    
    # 在线图片
    def listimageHandler(request):
        imageManagerListPath = GetConfigValue("imageManagerListPath")
        imageManagerAllowFiles = GetConfigValue("imageManagerAllowFiles")
        imagelistsize = GetConfigValue("imageManagerListSize")
        return listFileManage(request, imageManagerListPath, imageManagerAllowFiles, imagelistsize)
    
    
    # 在线文件
    def ListFileManagerHander(request):
        fileManagerListPath = GetConfigValue("fileManagerListPath")
        fileManagerAllowFiles = GetConfigValue("fileManagerAllowFiles")
        filelistsize = GetConfigValue("fileManagerListSize")
        return listFileManage(request, fileManagerListPath, fileManagerAllowFiles, filelistsize)
    
    
    actions = {
        "config": configHandler,
        "uploadimage": uploadimageHandler,
        "uploadvideo": uploadvideoHandler,
        "uploadfile": uploadfileHandler,
        "listimage": listimageHandler,
        "listfile": ListFileManagerHander
    }
    
    
    @csrf_exempt
    def handler(request):
        action = request.GET.get("action")
        return actions.get(action)(request)
    View Code

    配置此试图函数的路由,我是在应用下的url中设置的路由,这个根据自己的实际路径进行配置:

    from admin.views.controller import *
    path(r'ueEditorControler', handler)

    六、配置工作最后一步,将”ueditor.config.js”文件的

    , serverUrl: URL + "/net/controller.ashx" 

    修改为

     , serverUrl: "/ueEditorControler"

    主要就是在uediter.config.js中出发的请求这个视图函数,调用相应的后台

    配置完成!

    接下来是在js中使用编辑器:

    <script type="text/javascript">
        var ue = UE.getEditor('detail', {                
                    toolbars: [
                        [//'fullscreen',
                            //'source', 
                            'bold',
                            'underline', //下划线
                            'italic', //斜体
                            'insertorderedlist', //有序列表
                            'insertunorderedlist', //无序列表
                            '|',
                            'indent', //首行缩进
                            'justifyleft', //居左对齐
                            'justifyright', //居右对齐
                            'justifycenter', //居中对齐
                            'justifyjustify', //两端对齐 
                            '|',
                            'simpleupload', //单图上传
                            //'insertimage', //多图上传
                            //'map', //Baidu地图
                            'link', //超链接
                            '|',
                            'preview', //预览
                            'undo',
                            'redo'    
                        ]
                    ],
                }); 
    </script>
    <script type="text/javascript" src="/static/js/base/plugins/ueditor/ueditor.config.js"></script>
    <script type="text/javascript" src="/static/js/base/plugins/ueditor/ueditor.min.all.js"></script>

    完成!

    如果觉得此文档帮助了你,支持一下啊啊啊啊啊啊啊!

  • 相关阅读:
    JS系统函数
    匿名函数
    使用递归计算1~n之间所有整数的和
    交换两个变量的值
    创建函数,传递一个数字n,返回斐波那契数列的第n的值。
    创建函数function
    打印本世纪(2000~2100)的前10个闰年
    打印九九乘法表
    计算1~100之间所有整数的和
    循环执行
  • 原文地址:https://www.cnblogs.com/wangyuxing/p/13030394.html
Copyright © 2020-2023  润新知