1.DjangoUeditor
1.1 概述
富文本编辑器,在web开发中必不可少,但是django没有自带富文本编辑器,因此我们需要使用第三方库,这里使用DjangoUeditor
DjangoUditor是百度开源的在线HTML编辑器,功能非常强大,像表格可以直接拖动调整单元格大小
1.2 安装DjangoUeditor
该库存在bug,需要修改源码文件,因此使用源码文件安装。
-
新建项目
-
下载
从GitHub下载源码进行安装:https://github.com/twz915/DjangoUeditor3/下载完解压,在解压后的文件夹中有一个DjangoUeditor文件夹,后续需要使用
-
复制DjangoUeditor文件夹到项目根路径
-
在项目settings中添加子应用
-
根路由下添加包含子路由
2. UEditorField
UEditorField继承自models.TextField,因此可以直接将model里面定义的models.TextField直接改成UEditorField即可。
定义UEditorField时除了可以直接传入models.TextField提供的参数外,还可以传入UEditorField提供的额外的参数来控制UEditorField的外观、上传路径等。
UEditorField的参数如下
- width,height :编辑器的宽度和高度,以像素为单位
- toolbars :配置你想显示的工具栏,取值为mini,normal,full,代表小,一般,全部。如果默认的工具栏的按钮数量不符合您的要求,您可以在settings里面配置自己的显示按钮。参见后面介绍。
- imagePath :图片上传后保存的路径,如"images/“,实现上传到”{{MEDIA_ROOT}}/images"文件夹。 注意:如果imagePath值只设置文件夹,则未尾要有"/" imagePath可以按python字符串格式化:如"images/(basename)s_%(datetime)s_%(rnd)s.%(extname)s"。这样如果上传test.png,则文件会 被保存为"
{{MEDIA_ROOT}}/images/test_20440625122399_259.png"。imagePath中可以使用的变量有:
-time :上传时的时间,datetime.datetime.now().strftime(“%H%M%S”)- date :上传时的日期,datetime.datetime.now().strftime(“%Y%m%d”)
- datetime :上传时的时间和日期,
- datetime.datetime.now().strftime(“%Y%m%d%H%M%S”)
- year : 年
- month : 月
- day : 日
- rnd : 三位随机数,random.randrange(100,999)
- basename : 上传的文件名称,不包括扩展名
- extname : 上传的文件扩展名
- filename : 上传的文件名全称
- filePath : 附件上传后保存的路径,设置规则与imagePath一样。
- upload_settings : 字典例:upload_settings={imagePathFormat:“images/%(basename)s_%(datetime)s.%
(extname)s”, imageMaxSize:323232,fileManagerListPath:“files” }- upload_settings的内容就是static/ueditor/php/config.json里面的配置内容,因此,你可以去看config.json或者官方文档内容来决定 该如何配置upload_settings,基本上就是用来配置上传的路径、允许上传的文件扩展名、最大上传的文件大小之类的。
- 上面的imagePath和filePath被单独提取出来配置,原因是因为这两个参数是最常使用到的,imagePath就相当于upload_settings里面的 imagePathFormat,filePath就相当于upload_settings里面的filePathFormat。
- upload_settings里面设置了imagePathFormat,也可以在UeditorField里面设置imagePath,效果是一样的。但是如果两者均设置, 则imagePath优先级更高。
- 涂鸦文件、截图、远程抓图、图片库的xxxxPathFormat如果没有配置,默认等于imagePath.
- 远程文件库的xxxxPathFormat如果没有配置,默认等于filePath
- settings : 字典值,配置项与static/ueditor/ueditor.config.js里面的配置项一致。
- command : 可以为Ueditor新增一个按钮、下拉框、对话框,例
Description = UEditorField(u'描述'
,
blank=True, toolbars="full",
imagePath="cool/", settings={"a": 1},command=
[myBtn(uiName="mybtn1", icon="d.png",
title="aaa",
ajax_url="/ajaxcmd/"),myCombo(uiName="myCombo
3",title="ccc",initValue="111")])
- command 列表中的按钮是 commands 模块下 UEditorCommand 的实例列表:
- UEditorButtonCommand:可以在Ueditor上增加一个按钮
- UEditorComboCommand:可以在Ueditor上增加一个下拉框
- UEditorDialogCommand:可以在Ueditor上增加一个对话框,暂时未实现
- 也可以自定义:
from DjangoUeditor.commands import
UEditorButtonCommand,UEditorComboCommand
#定义自己的按钮命令类
class myBtn(UEditorButtonCommand):
def onClick(self):
return u"""
alert("爽!"); //这里可以
写自己的js代码
editor.execCommand(uiName);
""
def
onExecuteAjaxCommand(self,state):
""" 默认在command代码里面加入一段ajax代
码,如果指定了ajax_url和重载本方法,则在单点按钮后
会调用ajax_url.本方法重载是可选的。
"""
if state=="success":
return u"""
alert("后面比较
爽!"+xhr.responseText);//这里可以写ajax成功调用
的js代码
"""
if state=="error":
return u"""
alert("讨厌,摸哪里去
了!"+xhr.responseText);//这里可以写ajax错误调用
的js代码
"""
父类UEditorCommand有4个初始化参数:
- uiName:按钮名称
- title:按钮提示信息
- index:按钮显示的位置索引
- ajax_url:单击时调用的ajax url
- event_handler : 用来为Ueditor实例绑定事件侦听,比如以下示例的功能是:当选择区改变时将按
钮状态设置为禁
from DjangoUeditor.commands import
UEditorEventHandler
class
myEventHander(UEditorEventHandler)
def on_selectionchange(self):
return """
function getButton(btnName){
var items=%
(editor)s.ui.toolbars[0].items;
for(item in items){
if(items[item].name==btnName){
return
items[item];
}
}
}
var btn=getButton("mybtn1");
var
selRanage=id_Description.selection.getRange(
)
btn.setDisabled(selRanage.startOffset ==
selRanage.endOffset);
"""
说明:
我们可以继承UEditorEventHandler创建自己的事件侦听类,例如上面myEventHander,然后在
myEventHander中 增加on_eventname的方法,在里面返回侦听该event的js代码。例如上例
on_selectionchange,就会在前端js中 生成id_Description.addListener(‘selectionchange’,
function () {…});
如果要侦听contentchange事件,就在myEventHander中增加一个on_contentchange方法,然后
在该方法中返回js代码
3. 项目中应用富文本编辑器
富文本库的使用,都是为了提交带格式的内容,因此一般都是应用在模型上,我们新建一个模型:
from DjangoUeditor.models import UEditorField
class Article(models.Model):
title = models.CharField(max_length=100, verbose_name='标题')
# 富文本字段
content = UEditorField(
width=600,
height=300,
toolbars="full", # 全部的工具
imagePath="images/", #指定图片保存路径
filePath="files/", # 附件文件上传路径
upload_settings={"imageMaxSize":1204000}, # 最大图片大小
settings={},
verbose_name="内容",
blank = True, # 空白
null=True
)
class Meta:
verbose_name_plural = verbose_name = '文章'
迁移数据库后,使用Navicat连接
admin.py——使用admin管理模型
from django.contrib import admin
from ueditor_app.models import *
# Register your models here.
admin.site.register(Article)
settings:文件上传配置
import os
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
# 文件上传配置
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
根urls中配置——需要显示文件
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
创建superuser管理后台
4. 富文本编辑器列表显示
这里,我们将使用模板去显示富文本编辑器中的内容,以模板的形式
urls
from django.shortcuts import render
from ueditor_app.models import Article
# Create your views here.
def article_list(request):
# 查询所有的文章
article_list = Article.objects.all()
# 渲染页面
return render(request, "ueditor_app/article_list.html", {'article_list':article_list})
templates
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文章列表</title>
</head>
<body>
<ul>
{% for article in article_list %}
<li>
标题:{{article.title}}
</li>
{% endfor %}
</ul>
</body>
</html>
5. 富文本编辑器模板中使用新增文章——自定义富文本编辑器
使用ModelForm使用富文本
views
from django.shortcuts import render,redirect
from ueditor_app.models import Article
from ueditor_app.app_form import ArticleModelForm
# Create your views here.
def article_list(request):
# 查询所有的文章
article_list = Article.objects.all()
# 渲染页面
return render(request, "ueditor_app/article_list.html", {'article_list':article_list})
# 渲染到新增文章页面
def article(request):
form = ArticleModelForm
return render(request, "ueditor_app/article.html", {'form':form})
# 新增操作
def article_add(request):
form = ArticleModelForm(request.POST) # 获取表单提交的数据
# 判断是否有效
if form.is_valid():
form.save()
return redirect('ueditor_app:article_list')
template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>新增文章</title>
{{ form.media }}
</head>
<body>
<form action="{% url 'ueditor_app:article_add' %}" method="post">
{% csrf_token %}
<table>
{{ form }}
<tr><td><input type="submit" value="新增"></td></tr>
</table>
</form>
</body>
</html>
app_form.py
from django import forms
from ueditor_app.models import Article
class ArticleModelForm(forms.ModelForm):
class Meta:
# 可以理解成继承了Article的两个字段
model = Article
fields = ['title', 'content']
urls
from django.contrib import admin
from django.urls import path, include
from ueditor_app import views
app_name = 'ueditor_app'
urlpatterns = [
path('article_list/',views.article_list,name='article_list'),
path('article/',views.article, name='article'),
path('article_add/',views.article_add, name="article_add"),
]
6. 富文本编辑器模板中使用修改文章
views
# 获取要修改的文章,在修改页面渲染
def article_update(request):
# 获取id
id = request.GET.get('id')
# 根据id查询对象
article = Article.objects.get(pk=id)
form = ArticleModelForm(instance=article) # 指定对象
return render(request, 'ueditor_app/article_update.html',{'form':form})
# 点击表单进行修改文章修改文章
def article_update_submit(request):
# 获取修改文章的id
id = request.POST.get('id')
article = Article.objects.get(pk=id)
# request.POST表单中的文章, article要修改的文章
form = ArticleModelForm(request.POST,instance=article)
if form.is_valid():
form.save()
return redirect('ueditor_app:article_list')
templates
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
{{ form.media }}
</head>
<body>
<form action="{% url 'ueditor_app:article_update_submit' %}" method="post">
{% csrf_token %}
<input type="hidden" name="id" value="{{form.instance.id}}">
<table>
{{form}}
<tr><td><input type="submit" value="修改"></input></td></tr>
</table>
</form>
</body>
</html>