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>

完成!

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

原文地址:https://www.cnblogs.com/wangyuxing/p/13030394.html