本文使用 django-wysiwyg 来实现集成富文本编辑器到 Django Amdin 的编辑页面,只需要简单的配置,就可以集成任意你想使用的编辑器
django-wysiwyg
1.安装 django-wysiwyg
pip install django-wysiwyg 或
pip3 install django-wysiwyg
2.修改 settings.py
INSTALLED_APPS = (
...
'django_wysiwyg',
)
...
# mkeditor 是编辑器的名字
DJANGO_WYSIWYG_FLAVOR = "mkeditor"
3.创建 change_form.html
copy django_wysiwyg/templates/my-app-name/admin/change_form.html to my_app/templates/<my-app-name>/admin/change_form.html
4.为编辑器创建模板
因为要使用自定义的编辑器, 所以需要创建对应的模板 详情可以查看官方文档
# 找到 django-wysiwyg 的安装目录,新目录名称为编辑器的名字
cd django_wysiwyg/templates/django_wysiwyg
mkdir mkeditor
cd mkeditor
# 创建editor_instance.html 和 includes.html
editor_instance.html
<script type="text/javascript">
(function(){
var myEditor = MD.getEditor('id_body',{
name : 'body',
markdownHeight : '300px',
});
})();
/*
调用编辑器的时候有 name markdownWidth 和 markdownHeight三个配置项
name,就是表单提交时需要的name,可以自定义。markdownWidth和markdownHeight分别是编辑器的宽和高,默认是100%
id_body 为要替换 Django Admin 页面的文本框的 id 属性值
*/
</script>
includes.html
editor_api.js 为编辑器接口 JS
{% load wysiwyg %}
{% load static %}
<script src="{% static 'mkeditor/editor_api.js' %}"></script>
<script type="text/javascript">
// allow custom settings per editor ID:
var django_wysiwyg_editor_configs = [];{% block django_wysiwyg_editor_config %}
var django_wysiwyg_editor_config = {};
{% endblock %}
var django_wysiwyg =
{
editors: {},
enable: function django_wysiwyg_enable(editor_name, field_id, config)
{
if( !config ) {
config = django_wysiwyg_editor_configs[field_id] || django_wysiwyg_editor_config;
}
if( !this.editors[editor_name] ) {
this.editors[editor_name] = mkeditor.replace(field_id, config);
}
},
disable: function django_wysiwyg_disable(editor_name)
{
var editor = this.editors[editor_name];
if( editor ) {
editor.destroy(/*noUpdate=*/false);
this.editors[editor_name] = null;
}
},
is_loaded: function django_wysiwyg_is_loaded()
{
return window.mkeditor != null;
}
}
</script>
5.修改 Admin 模板
# app/admin.py
from django.contrib import admin
from app.models import Model
class ModelAdmin(admin.ModelAdmin):
...
change_form_template = 'blog/admin/change_form.html'
admin.site.register(Model, ModelAdmin)
mkeditor
1.下载编辑器
git clone https://github.com/chengxuzhang/mymarkdown.git
2.解压
将压缩包解压到 app/static/mkeditor 目录
3.修改文件路径
因为原文件里面很多使用相对路径,导致引入到 Django 后无法访问
/static/mkeditor/editor_api.js
baseURL = ''; 改为 baseURL = '/static/mkeditor/';
/static/mkeditor/_src/style.js
改为
var paths = [
"/static/mkeditor/codemirror/lib/codemirror.css",
"/static/mkeditor/themes/base16-light.css",
"/static/mkeditor/themes/default.css",
"/static/mkeditor/bootstrap/dist/css/bootstrap.min.css",
"/static/mkeditor/font/iconfont.css",
"/static/mkeditor/themes/editor.css",
]
/static/mkeditor/plugins/toolbars.js
imagePaste.src = "plugins/image/paste.js";
改为
imagePaste.src = "/static/mkeditor/plugins/image/paste.js";
/static/mkeditor/_src/lang/lang.js
src="_src/lang/'+ MD.language +'.js"
改为
src="/static/mkeditor/_src/lang/'+ MD.language +'.js"
4.修改编辑器样式
直接替换的话,编辑器会覆盖掉标题部分。所以需要稍微修改一下样式
/static/mkeditor/themes/editor.css
.markdown-editor{
...
margin-left:0px;
...
}
改为
.markdown-editor{
...
margin-left:160px;
...
}
django_wysiwyg/templates/django_wysiwyg/mkeditor/editor_instance.html
<script type="text/javascript">
(function(){
var myEditor = MD.getEditor('id_body',{
name : 'body',
markdownHeight : '300px',
markdownWidth : '90%',
});
})();
/static/mkeditor/plugins/toolbars.js
因为上面的修改导致编辑器会向右偏移 160px,所以全屏模式要覆盖掉之前的修改
markdownDiv.setAttribute("style","width:100%;height:"+(document.documentElement.clientHeight-30)+"px;position:fixed;left:0;top:0;");
改为
markdownDiv.setAttribute("style","margin-left:0px;width:100%;height:"+(document.documentElement.clientHeight-30)+"px;position:fixed;left:0;top:0;");
5.修改编辑器设置
/static/mkeditor/config/main.js
作者是用 php 提供图片上传功能, 由于要引入到 Django, 所以需要用 Python 重写
(function(){
MARKDOWN_CONFIG = {
toolbars : ['Bold', 'Italic', '|', 'Link', 'Quote', 'Code', 'Image', '|', 'Ul', 'Ol', 'Title', 'Hr', 'Table', '|', 'Cancel', 'Sure', '|', 'Question', 'Left', 'EditView', 'Right', 'FullScreen'],
path : '/upload/', // 图片上传路径,用于匹配路由
language : 'zh-CN',
name : 'body', // 表单提交时候的name值
size : 5 * 1024 * 1024,
}
})();
至此, 编辑器已成功替换。 但是点击图片上传没有反应。
Python 实现图片上传
1.添加 settings 设置
PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
...
# Upload Image
MEDIA_URL = '/static/media/'
# 本地测试
MEDIA_ROOT = os.path.join(PROJECT_PATH, 'static/media')
# 使用 Nginx 代理
# MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media')
2.添加路由
from django.conf.urls import url
from app import views
urlpatterns = [
...
url(r'^upload/', view=views.Upload, name='upload'),
]
3.添加视图函数
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
...
def Upload(request):
if request.method == 'POST':
# 获取图片对象,生成图片保存路径 app/static/media/upload_date/image_name
# 生成图片 url 返回给前端 /static/media/upload_date/image_name
image = request.FILES['files']
date = datetime.datetime.now().strftime('%Y%m%d')
img_dir = os.path.join(settings.MEDIA_ROOT, date)
img_save_path = os.path.join(img_dir, image.name)
default_storage.save(img_save_path, ContentFile(image.read()))
img_path = os.path.join(os.path.join(settings.MEDIA_URL, date), image.name)
content = json.dumps({'status': 200, 'store_path': img_path})
return HttpResponse(content)
4.添加 csrf_token
/static/mkeditor/plugins/image/paste.js
...
fd.append("files", file);
var csrfmiddlewaretoken = document.getElementsByName('csrfmiddlewaretoken')[0].attributes['value'].value;
fd.append("csrfmiddlewaretoken", csrfmiddlewaretoken);
现在就可以正常的使用图片上传功能了。