最新消息:欢迎光临 魔力 • Python!大家可以点开导航菜单中的【学习目录】,这个目录类似图书目录,更加方便学习!

Django2练习项目:开发个人博客系统(12)

Django教程 小楼一夜听春语 11271浏览 0评论

这一篇教程,我们一起学习如何在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)

头像
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网站 (可选)

网友最新评论 (13)

  1. 头像
    小楼,ckeditor获取不到CKEditorFuncNum怎么办?上传图片的时候, res = "window.parent.CKEDITOR.tools.callFunction(" + callback + ",'/" + file_name + "', '');"这一步中,callback是none类型呀。昨天折腾了一下午,也没弄好。
    木木5年前 (2018-11-21)回复
    • 小楼一夜听春语
      新版的上传功能应该是不用自己写的,只需要相关配置即可,具体可以查看相关文档:https://pypi.org/project/django-ckeditor/#description
      小楼一夜听春语5年前 (2018-11-21)回复
      • 头像
        确定不用自己写view。但是图片居中怎么搞啊?我是说文章中上的图片。
        木木5年前 (2018-11-21)回复
        • 小楼一夜听春语
          图片居中和上传代码没什么关系。
          小楼一夜听春语5年前 (2018-11-21)回复
  2. 头像
    你好,请问上传图片修改的view.py是修改ckeditor里面的文件吗
    ritter5年前 (2018-11-21)回复
    • 小楼一夜听春语
      不是
      小楼一夜听春语5年前 (2018-11-21)回复
      • 头像
        上传图片请求的URL是哪个鸭
        ritter5年前 (2018-11-21)回复
        • 头像
          😛
          qq5年前 (2018-12-26)回复
      • 头像
        re_path(r'^media/(?P.*)$', serve, {'document_root': settings.MEDIA_ROOT}) 这一句的作用又是什么 谢谢楼主
        ritter5年前 (2018-11-21)回复
  3. 头像
    楼主求助
    ritter5年前 (2018-11-21)回复
    • 头像
      请问你那个CKEditorFuncNum找不到的问题解决了吗,我也是找不到一直都是none
      求带求带5年前 (2019-03-27)回复
  4. 头像
    那个CKEditorFuncNum参数找不到的问题,跟ckeditor配置问题,参考:https://www.codepalace.xyz/article_show/34,我也找了好久
    junxue5年前 (2019-03-31)回复
    • 小楼一夜听春语
      good
      小楼一夜听春语5年前 (2019-04-01)回复