社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Django

Django搭建个人博客:使用django-ckeditor富文本编辑器

杜赛_dusai • 6 年前 • 787 次点击  
阅读 46

Django搭建个人博客:使用django-ckeditor富文本编辑器

前面我们已经实现了用Markdown语法写文章了。但是文章的评论用Markdown就不太合适了,你不能强求用户也花时间去熟悉语法啊。另外评论中通常还有表情、带颜色的字体等功能,这些也是Markdown不具备的。

因此富文本编辑器Django-ckeditor就派上用场了。

在后台使用Ckeditor

虚拟环境中安装django-ckeditor:

(env) > pip install django-ckeditor
复制代码

安装成功后还是老规矩,在settings.py中注册app:

my_blog/settings.py

...
INSTALLED_APPS = [
    ...
    
    'ckeditor',

    ...
]
...
复制代码

接下来需要修改模型了。用django-ckeditor库自己的富文本字段RichTextField替换普通的文本字段TextField

comment/models.py

...
# django-ckeditor
from ckeditor.fields import RichTextField

class Comment(models.Model):
    ...
    # 之前为 body = models.TextField()
    body = RichTextField()
    ...
复制代码

记得每次修改模型后要迁移数据

(env) > python manage.py makemigrations
(env) > python manage.py migrate
复制代码

为方便测试,修改comment/admin.py文件,将评论模块注册到后台中:

comment/admin.py

from django.contrib import admin
from .models import Comment

admin.site.register(Comment)
复制代码

启动服务器,进入后台的评论页面,发现已经可以使用django-ckeditor了:

img

功能相当齐全,字体、字号、颜色、链接、表情应有尽有。

如果我只需要部分功能怎么办呢?比如插入flash动画基本就用不到。另外似乎也没看到插入代码块的功能。

ckeditor允许你在settings.py中进行自定义配置:

my_blog/settings.py

...
CKEDITOR_CONFIGS = {
    # django-ckeditor默认使用default配置
    'default': {
        # 编辑器宽度自适应
        'width':'auto',
        'height':'250px',
        # tab键转换空格数
        'tabSpaces': 4,
        # 工具栏风格
        'toolbar': 'Custom',
        # 工具栏按钮
        'toolbar_Custom': [
            # 表情 代码块
            ['Smiley', 'CodeSnippet'], 
            # 字体风格
            ['Bold', 'Italic', 'Underline', 'RemoveFormat', 'Blockquote'],
            # 字体颜色
            ['TextColor', 'BGColor'],
            # 链接
            ['Link', 'Unlink'],
            # 列表
            ['NumberedList', 'BulletedList'],
            # 最大化
            ['Maximize']
        ],
        # 加入代码块插件
        'extraPlugins': ','.join(['codesnippet']),
    }
}
复制代码

toolbar_Custom中定义需要使用的功能模块;没列出的功能就不再显示了。代码块功能是编辑器自带的插件,需要在extraPlugins中指定使用。效果如下:

img

编辑富文本搞定后,还需要在前台界面中展示出来。富文本是以类似html的格式进行保存的,因此还要在展示评论的代码加入|safe过滤器,防止浏览器进行转义。

修改detail.html中展示评论的部分代码:

templates/article/detail.html

...

<!-- 显示评论 -->
<h4>共有{{ comments.count }}条评论</h4>
<div>
    {% for comment in comments %}
        ...
        <!-- 修改这里 -->
        <div>{{ comment.body|safe }}</div>
    {% endfor %}
</div>

...
复制代码

进入文章详情页面看看效果:

img

代码高亮

代码高亮需要添加额外的插件Prism。在Prism插件官方页面下载(也可以点击这里直接下载)后,将解压出来的prism放到env\Lib\site-packages\ckeditor\static\ckeditor\ckeditor\plugins目录下。注意env是你创建的虚拟环境的目录。

之前你安装的所有库都在这个env目录中的。

然后在Prism官网选择主题:

img

  • 根据喜好选择一个喜欢的主题
  • 然后选择需要高亮的语言。不清楚就可以全选
  • 勾选行号插件
  • 最后点击DOWNLOAD CSS下载样式

static目录中新建prism目录,将下载好的CSS文件放进去。

注意这里的static是项目中的静态文件目录(与前面的章节相同),而不是env文件夹中的static目录。

然后在需要代码高亮的模板文件中引用prism的静态文件,对代码进行渲染:

templates/article/detail.html

...




    
<script src="{% static 'ckeditor/ckeditor/plugins/prism/lib/prism/prism_patched.min.js' %}"></script>
<link rel="stylesheet" href="{% static 'prism/prism.css' %}">

...
复制代码

Prismwidgetlineutils插件添加到配置文件中。后面两个编辑器自带,不用单独下载,添上就可以了:

my_blog/settings.py

...
CKEDITOR_CONFIGS = {
    'default': {
        ...
        # 添加 Prism 相关插件
        'extraPlugins': ','.join(['codesnippet', 'prism', 'widget', 'lineutils']),
    }
}
复制代码

这样就完成了:

img

代码高亮效果不错!

在前台使用Ckeditor

为了让用户在前台也能使用富文本编辑器,还得对代码稍加改动。

首先需要把评论的表单传递到文章详情页面中。因此修改article_detail视图:

article/views.py

...
# 引入评论表单
from comment.forms import CommentForm

...
# 文章详情
def article_detail(request, id):
    ...
    
    # 引入评论表单
    comment_form = CommentForm()
    context = { 
        ...
        'comment_form': comment_form,
    }
    ...
复制代码

然后将detail.html原来评论表单中的正文部分(即前面章节写的<textarea>)替换如下:

templates/article/detail.html

...

<!-- 发表评论 -->
<form ...>
{% csrf_token %}
    <div class="form-group">
        <label for="body">...</label>
        
        <!-- 将之前的<textarea>替换掉 -->
        <!-- <textarea type="text" 
                       class="form-control" 
                       id="body" 
                       name="body" 
                       rows="2"></textarea>  -->
        <div>
            {{ comment_form.media }}
            {{ comment_form.body }}
        </div>
        
    </div>
    <!-- 提交按钮 -->
    ...                   
</form>

...
复制代码

其中的comment_form.media是编辑器自身的渲染代码,comment_form.body则是评论正文字段。

看看效果:

img

不错,编辑器已经可以正常使用了,但还有一个小问题:似乎编辑器宽度没有自适应,右边大片白白的空间也太浪费了。继续努力。

宽度自适应

首先在配置文件中将宽度设置为auto,这一步我们已经做好了。

Ckeditor编辑器本身有一个inline-block的样式,阻碍了自适应效果,需要用Jquery语法将其清除掉。在详情页面底部加入代码:

templates/article/detail.html

<!-- 注意这是错误的示范! -->

...
<!-- 新增代码 -->
<script>
    $(".django-ckeditor-widget").removeAttr('style');
</script>

<!-- 这个已经有了 -->
{% endblock content %}
复制代码

$符号代表Jquery语句。这句的意思是:找到页面中class='django-ckeditor-widget'的容器,然后删除这个容器的style属性。

看似没什么问题,然而Bug藏在细节中。注意这是个Jquery语句,那么就要求运行之前先载入Jquery.js。然而在渲染页面时,包含$语句的{% block content %}会插入到base.html模板的Jquery.js标签的前面,导致语句不会生效,并且控制台会报出$ is not defined的错误。

比较容易想到的办法是将引入Jquery.js的标签提到更顶部的位置,在block模板插入前就加载。这样做的问题是JS文件加载通常较慢,它会阻塞后面的代码,从而减缓页面整体加载速度。本文不采用这种办法。

解决方案是在base.html中新增专门用于拼接JavaScript脚本的位置,命名为{% block script %}。注意它必须放置在Jquery标签的后面:

templates/base.html

...

<body>
    ...
    <!-- 已有代码 -->
    <script src="{% static 'jquery/jquery-3.3.1.js' %}"></script>
    ...
    <!-- 新增代码 -->
    {% block script %}{% endblock script %}
</body>
复制代码

然后将detail.html中的JS代码放到这个块中:

templates/article/detail.html

...

{% block script %}
<script>
    $(".django-ckeditor-widget").removeAttr('style');
</script>
{% endblock script %}
复制代码

这种方法可以灵活的定义JS脚本的运行顺序,并且代码看起来更加整洁。推荐所有的JS代码都采取这种方法插入。

刷新页面,编辑器就能够宽度自适应了:

img

发表含有代码块的评论,详情页面的显示如下:

img

总结

现在,博文和其评论都可以漂亮的排版了。对于有些不喜欢Markdown的人来说,甚至可以连博文都使用django-cdeditor提供的富文本编辑器。我自己还是倾向用Markdown写文章:写作效率比好看更重要,并且主流网站几乎都支持Markdown,多平台发稿很方便。

感谢Aaron Zhao 的个人博客提供了本文的参考。博主还讲解了django-ckeditor上传图片的设置,有兴趣可以前往了解。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/30071
 
787 次点击