这一篇教程,我们一起学习如何在Django2项目中使用富文本编辑器Django-CKEditor。
提示:另一款富文本编辑器“SummerNote”的使用教程请参考《Django2:Web项目开发入门笔记(26)》。
例如,我们在Django后台中编辑文章内容时,就需要富文本编辑器。
一、安装
如果使用Django-CKEditor,我们需要先安装依赖库Pillow。
pip install pillow
然后,安装Django-CKEditor。
pip install django-ckeditor
二、设置
完成Django-CKEditor的安装后,打开文件“settings.py”,添加如下设置。
1、“INSTALLED_APPS”中添加“ckeditor”和“ckeditor_uploader’”。
示例代码:
INSTALLED_APPS = ( ...省略部分代码... 'ckeditor', 'ckeditor_uploader' )
2、添加Media相关配置
示例代码:
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
3、添加CKEditor文件上传路径。
示例代码:
CKEDITOR_UPLOAD_PATH = "upload/" # 注意只有右侧带有“/”
4、添加CKEditor加载配置。
示例代码:
CKEDITOR_CONFIGS = { 'default': { # 添加默认配置 }, 'mycfg': { # 添加自定义配置 'skin': 'moono', # 设置皮肤 'toolbar': 'full', # 设置工具栏加载全部功能 'width': '100%', # 设置宽度 }, }
可以预先定义多种配置(例如上方代码中的“mycfg”),以便在不同的应用场景中调用不同的配置。
更多配置项请参考:https://pypi.org/project/django-ckeditor/#example-ckeditor-configuration
关于CKEditor的简体中文语言设置:
作者电脑上显示默认繁体中文,检查后发现原因在于CKEditor会使用“settings.py”文件中的语言设置。
Django使用简体中文时,我们的设置为“LANGUAGE_CODE = ‘zh-Hans’”,这是因为Django2语言文件夹中没有“zh-cn”文件夹,简体中文是“zh-Hans”文件夹,直接设置“LANGUAGE_CODE = ‘zh-cn’”会导致异常。
但是这样的设置又会导致CKEditor找不到名为“zh-Hans.js”的语言文件,当找不到文件时,CKEditor会找到第一个名称包含“zh”的js文件去调用。
所以,解决方案是修改Django语言文件夹或者CKEditor语言文件的名称,让他们保持统一。
不过CKEditor的语言文件的名称在PyCharm中提示不能更改,最终只好修改Django的简体中文语言文件夹名称为“zh-cn”,并将“settings.py”文件中的语言设置改为“LANGUAGE_CODE = ‘zh-cn’”。
提示:Django语言文件夹所在路径为:(venv)\Lib\site-packages\django\conf\locale
另外一种解决方案是将繁体中文的语言文件“zh.js”内容替换成了”zh-cn.js”中的简体内容。
示例代码:
CKEDITOR.lang['zh']={"editor":"所见即所得编辑器"...省略后方代码...
注意上方代码中标红的部分,要在替换了内容之后改回“zh”。
5、URL配置
打开文件“urls.py”,在“urlpatterns”列表中,包含CKEditor的URL配置。
示例代码:
path('ckeditor/', include('ckeditor_uploader.urls')),
三、使用
打开文件“models.py”,导入ckeditor模块中的字段类,修改文章类“Article”中的“content”字段。
示例代码:
from ckeditor.fields import RichTextField
class Article(models.Model): ...省略部分代码... content = RichTextField('内容') ...省略部分代码...
在上方代码中,使用了“RichTextField”字段,默认会调用“settings.py”中的“default”设置,如果需要使用我们添加的自定义设置“mycfg”,可以在“RichTextField”的参数中进行指定。
示例代码:
content = RichTextField('内容',config_name='mycfg')
通过以上步骤的设置,我们就可以在Django后台中使用富文本编辑器了。
如果在我们自己编写的页面中使用CKEditor,需要在模板中(例如“base.html”)添加如下代码。
示例代码:
<script src="{% static '/ckeditor/ckeditor/ckeditor.js' %}"></script> <script src="{% static '/ckeditor/ckeditor-init.js' %}"></script>
不过,通过以上的操作,我们还不能够在富文本编辑器中使用图片上传的功能。
四、设置图片上传
首先,打开文件“\venv\Lib\site-packages\ckeditor\static\ckeditor\ckeditor\config.js”(本案例使用了虚拟环境)。
在打开的文件中添加配置。
示例代码:
CKEDITOR.editorConfig = function (config) {
config.filebrowserImageUploadUrl = "/upload/";
};
上方代码中,红色部分为新增代码。
添加这一段代码之后,在富文本编辑器中点击图片的图标会出现新的标签“上传”。
然后,我们还需要在视图文件“views.py”中编写一段上传文件的代码。
但是,因为Django自带防止跨域攻击的检查功能,还会导致上传会失败,所以,我们为这一段代码禁用跨域攻击检查。
示例代码:
import time from django.shortcuts import Http404 # 导入404异常类 from django.views.decorators.csrf import csrf_exempt # 导入禁用跨域攻击检查的装饰器 @csrf_exempt # 装饰上传图片的视图函数 def image_upload(request): # 定义上传图片的视图函数 if request.method == 'POST': callback = request.GET.get('CKEditorFuncNum') # 获取客户端上传事件的标记 try: path = "media/upload/" + time.strftime("%Y%m%d%H%M%S", time.localtime()) f = request.FILES["upload"] # 获取上传文件的对象 file_name = path + "_" + f.name # 组织文件存储路径与名称 with open(file_name, "wb+") as file: # 创建文件 for chunk in f.chunks(): # 读取上传文件 file.write(chunk) # 写入文件 except Exception as e: print(e) res = "<script>window.parent.CKEDITOR.tools.callFunction(" + callback + ",'/" + file_name + "', '');</script>" # 将上传文件的路径通过上传事件的标记写回浏览器客户端 return HttpResponse(res) # 返回响应内容 else: raise Http404() # 抛出异常
添加完上述代码之后,我们进行URL配置。
示例代码:
...省略部分代码... from django.urls import re_path from . import settings from django.views.static import serve urlpatterns = [ ...省略部分代码... path('upload/', blog_view.image_upload), re_path(r'^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT}) ]
最后,在项目根目录下添加“media”文件夹并在“media”文件夹下添加“upload”文件夹,以保证文件能够正常上传。
当然,“upload”文件夹也可以在图片上传的视图函数中通过代码创建。
到这里,我们就能够正常的使用图片上传功能了。
转载请注明:魔力Python » Django2练习项目:开发个人博客系统(12)